From 5440285c9b80e15f8d820a8fb600a0641df9676e Mon Sep 17 00:00:00 2001 From: timchen1002 <365931026@qq.com> Date: Thu, 20 Jan 2022 19:27:43 +0800 Subject: [PATCH] update --- Assets/Editor/Utils/PlayerPrefsTools.cs | 11 - Assets/GameRes/BaseRes/UpdatePanel.prefab | 34 +- Assets/LuaFramework/Editor/CustomSettings.cs | 34 +- Assets/LuaFramework/Luajit/Build.bat | 31 - Assets/LuaFramework/Luajit/jit/bc.lua | 190 - Assets/LuaFramework/Luajit/jit/bcsave.lua | 661 -- .../LuaFramework/Luajit/jit/bcsave.lua.meta | 4 - Assets/LuaFramework/Luajit/jit/dis_arm.lua | 689 -- Assets/LuaFramework/Luajit/jit/dis_mips.lua | 428 - Assets/LuaFramework/Luajit/jit/dis_mipsel.lua | 17 - .../Luajit/jit/dis_mipsel.lua.meta | 4 - Assets/LuaFramework/Luajit/jit/dis_ppc.lua | 591 -- .../LuaFramework/Luajit/jit/dis_ppc.lua.meta | 4 - Assets/LuaFramework/Luajit/jit/dis_x64.lua | 17 - .../LuaFramework/Luajit/jit/dis_x64.lua.meta | 4 - Assets/LuaFramework/Luajit/jit/dis_x86.lua | 928 -- .../LuaFramework/Luajit/jit/dis_x86.lua.meta | 4 - Assets/LuaFramework/Luajit/jit/dump.lua | 707 -- Assets/LuaFramework/Luajit/jit/dump.lua.meta | 4 - Assets/LuaFramework/Luajit/jit/v.lua | 170 - Assets/LuaFramework/Luajit/jit/v.lua.meta | 4 - Assets/LuaFramework/Luajit/jit/vmdef.lua | 331 - Assets/LuaFramework/Luajit/jit/vmdef.lua.meta | 4 - Assets/LuaFramework/Luajit/lua51.dll | Bin 375296 -> 0 bytes Assets/LuaFramework/Luajit/luajit.exe | Bin 86016 -> 0 bytes .../Scripts/Common/LuaBehaviour.cs | 10 + .../Common/LuaBehaviour.cs.meta} | 2 +- .../LuaFramework/Scripts/Common/LuaLoader.cs | 106 - .../Scripts/ConstDefine/AppConst.cs | 29 +- .../Scripts/ConstDefine/ManagerName.cs | 16 +- .../Controller/Command/SocketCommand.cs | 16 - .../Scripts/Framework/AppFacade.cs | 35 +- .../Scripts/Framework/Core/Base.cs | 57 +- .../Scripts/Framework/Core/Facade.cs | 60 +- .../Scripts/Framework/Core/Manager.cs | 16 - .../Scripts/Framework/Core/Message.cs | 94 - .../Scripts/Framework/Core/View.cs | 11 - .../Scripts/Manager/GameManager.cs | 63 - .../Scripts/Manager/GameManager.cs.meta | 8 - .../Manager/Interface/ITimerBehaviour.cs | 8 - .../Manager/Interface/ITimerBehaviour.cs.meta | 8 - .../Scripts/Manager/LuaManager.cs | 162 +- .../Scripts/Manager/NetworkManager.cs | 142 +- .../LuaFramework/Scripts/Network/HeartBeat.cs | 69 + .../Network/HeartBeat.cs.meta} | 2 +- .../Scripts/Network/ProtoEncrypt.cs | 226 + .../Scripts/Network/ProtoEncrypt.cs.meta} | 2 +- .../Scripts/Network/SocketClient.cs | 38 +- .../Scripts/Network/SocketClient.cs.meta | 5 +- .../LuaFramework/Scripts/Utility/LuaHelper.cs | 33 +- Assets/LuaFramework/Scripts/Utility/Util.cs | 370 +- .../LuaFramework/Scripts/Utility/WrapCSObj.cs | 70 + .../Utility/WrapCSObj.cs.meta} | 2 +- Assets/LuaFramework/Scripts/View/AppView.cs | 76 - .../ToLua/BaseType/UnityEngine_LightWrap.cs | 1487 --- .../BaseType/UnityEngine_MeshRendererWrap.cs | 273 - .../UnityEngine_ParticleSystemWrap.cs | 1392 --- Assets/LuaFramework/ToLua/Core/LuaDLL.cs | 1 + .../LuaFramework/ToLua/Core/LuaFileUtils.cs | 142 +- Assets/LuaFramework/ToLua/Core/LuaFunction.cs | 2 +- Assets/LuaFramework/ToLua/Core/LuaState.cs | 80 +- Assets/LuaFramework/ToLua/Core/LuaStatePtr.cs | 95 +- Assets/LuaFramework/ToLua/Core/ToLua.cs | 6 + Assets/LuaFramework/ToLua/Misc/LuaLooper.cs | 157 +- .../Framework/Common.meta} | 2 +- .../Framework/Common/Global.meta} | 5 +- .../Framework/Common/Global/GlobalObjs.cs | 10 + .../Common/Global/GlobalObjs.cs.meta | 11 + .../Framework/Common/Misc.meta} | 6 +- .../Framework/Common/Misc/ObjectParser.cs | 83 + .../Common/Misc/ObjectParser.cs.meta | 11 + .../Framework/Common/Util.meta} | 6 +- .../Scripts/Framework/Common/Util/XMLUtil.cs | 244 + .../Framework/Common/Util/XMLUtil.cs.meta | 11 + .../Framework/Event/EventDispatcher.cs | 15 + Assets/Scripts/Framework/I18N.meta | 8 + Assets/Scripts/Framework/I18N/I18CfgItem.cs | 7 + .../Scripts/Framework/I18N/I18CfgItem.cs.meta | 11 + Assets/Scripts/Framework/I18N/I18N.cs | 48 + Assets/Scripts/Framework/I18N/I18N.cs.meta | 11 + Assets/Scripts/Framework/Log/GameLogger.cs | 23 +- Assets/Scripts/Framework/Log/LogMgr.cs | 18 +- Assets/Scripts/Framework/Network.meta | 8 + Assets/Scripts/Framework/Network/ClientNet.cs | 37 + .../Framework/Network/ClientNet.cs.meta | 11 + .../Framework/Network/INetStateListener.cs | 16 + .../Network/INetStateListener.cs.meta | 11 + .../Framework/Network/NetDataAnalysis.cs | 115 + .../Framework/Network/NetDataAnalysis.cs.meta | 11 + .../Framework/Network/RemoteConnection.cs | 714 ++ .../Network/RemoteConnection.cs.meta | 11 + .../Framework/Network/SocketPackageQueue.cs | 48 + .../Network/SocketPackageQueue.cs.meta | 11 + Assets/Scripts/Framework/Panel/BasePanel.cs | 136 +- Assets/Scripts/Framework/Panel/PanelMgr.cs | 104 +- .../Framework/Prefab/PrefabObjBinder.cs | 3 + .../Framework/Resource/AssetBundleMgr.cs | 189 + .../Framework/Resource/AssetBundleMgr.cs.meta | 11 + .../Scripts/Framework/Resource/ConfigItem.cs | 108 + .../Framework/Resource/ConfigItem.cs.meta | 11 + .../Scripts/Framework/Resource/ResourceCfg.cs | 51 - .../Framework/Resource/ResourceCfg.cs.meta | 11 - .../Framework/Resource/ResourceConfigItem.cs | 39 + .../Resource/ResourceConfigItem.cs.meta | 11 + .../Scripts/Framework/Resource/ResourceMgr.cs | 159 +- .../Framework/Resource/ResourceMgr.cs.meta | 2 +- .../Framework/Resource/ResourcePathBuilder.cs | 38 + .../Resource/ResourcePathBuilder.cs.meta | 11 + Assets/Scripts/Framework/SprotoDef.meta | 8 + Assets/Scripts/Framework/SprotoDef/c2s.cs | 21 + .../Framework/SprotoDef/c2s.cs.meta} | 4 +- Assets/Scripts/Framework/SprotoDef/s2c.cs | 14 + .../Framework/SprotoDef/s2c.cs.meta} | 4 +- Assets/Scripts/Framework/sproto.meta | 8 + .../Framework/sproto/src.meta} | 2 +- .../Scripts/Framework/sproto/src/SpCodec.cs | 478 + .../Framework/sproto/src/SpCodec.cs.meta} | 2 +- Assets/Scripts/Framework/sproto/src/SpDict.cs | 103 + .../Framework/sproto/src/SpDict.cs.meta} | 2 +- .../Scripts/Framework/sproto/src/SpField.cs | 34 + .../Framework/sproto/src/SpField.cs.meta} | 2 +- .../Scripts/Framework/sproto/src/SpObject.cs | 443 + .../Framework/sproto/src/SpObject.cs.meta} | 2 +- .../Scripts/Framework/sproto/src/SpPacker.cs | 183 + .../Framework/sproto/src/SpPacker.cs.meta | 8 + .../Framework/sproto/src/SpProtoParser.cs | 185 + .../sproto/src/SpProtoParser.cs.meta | 8 + .../Framework/sproto/src/SpProtocol.cs | 25 + .../Framework/sproto/src/SpProtocol.cs.meta | 8 + Assets/Scripts/Framework/sproto/src/SpRpc.cs | 285 + .../Framework/sproto/src/SpRpc.cs.meta | 8 + .../Scripts/Framework/sproto/src/SpStream.cs | 210 + .../Framework/sproto/src/SpStream.cs.meta | 8 + .../Framework/sproto/src/SpStreamCache.cs | 40 + .../sproto/src/SpStreamCache.cs.meta | 8 + Assets/Scripts/Framework/sproto/src/SpType.cs | 161 + .../Framework/sproto/src/SpType.cs.meta | 8 + .../Framework/sproto/src/SpTypeManager.cs | 119 + .../sproto/src/SpTypeManager.cs.meta | 8 + .../Framework/sproto/src/SprotoUtil.cs | 170 + .../Framework/sproto/src/SprotoUtil.cs.meta | 11 + Assets/Scripts/HOTween.meta | 8 + .../HOTween/Editor.meta} | 2 +- .../HOTween/Editor/HOTweenV1_Editor.dll | Bin 0 -> 12288 bytes .../HOTween/Editor/HOTweenV1_Editor.dll.mdb | Bin 0 -> 2205 bytes .../Editor/HOTweenV1_Editor.dll.mdb.meta} | 2 +- .../HOTween/Editor/HOTweenV1_Editor.dll.meta} | 15 +- Assets/Scripts/HOTween/HOTween.XML | 8450 +++++++++++++++++ Assets/Scripts/HOTween/HOTween.XML.meta | 4 + Assets/Scripts/HOTween/HOTween.dll | Bin 0 -> 109568 bytes Assets/Scripts/HOTween/HOTween.dll.mdb | Bin 0 -> 55200 bytes .../HOTween/HOTween.dll.mdb.meta} | 2 +- Assets/Scripts/HOTween/HOTween.dll.meta | 23 + Assets/Scripts/HOTween/HOTween_License.txt | 7 + .../Scripts/HOTween/HOTween_License.txt.meta | 4 + Assets/Scripts/Main.cs | 42 +- Assets/Scripts/View/HotUpdatePanel.cs | 26 +- 157 files changed, 14523 insertions(+), 9291 deletions(-) delete mode 100644 Assets/Editor/Utils/PlayerPrefsTools.cs delete mode 100644 Assets/LuaFramework/Luajit/Build.bat delete mode 100644 Assets/LuaFramework/Luajit/jit/bc.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/bcsave.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/bcsave.lua.meta delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_arm.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_mips.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_mipsel.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_mipsel.lua.meta delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_ppc.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_ppc.lua.meta delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_x64.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_x64.lua.meta delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_x86.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/dis_x86.lua.meta delete mode 100644 Assets/LuaFramework/Luajit/jit/dump.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/dump.lua.meta delete mode 100644 Assets/LuaFramework/Luajit/jit/v.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/v.lua.meta delete mode 100644 Assets/LuaFramework/Luajit/jit/vmdef.lua delete mode 100644 Assets/LuaFramework/Luajit/jit/vmdef.lua.meta delete mode 100644 Assets/LuaFramework/Luajit/lua51.dll delete mode 100644 Assets/LuaFramework/Luajit/luajit.exe create mode 100644 Assets/LuaFramework/Scripts/Common/LuaBehaviour.cs rename Assets/LuaFramework/{ToLua/BaseType/UnityEngine_MeshRendererWrap.cs.meta => Scripts/Common/LuaBehaviour.cs.meta} (83%) delete mode 100644 Assets/LuaFramework/Scripts/Common/LuaLoader.cs delete mode 100644 Assets/LuaFramework/Scripts/Controller/Command/SocketCommand.cs delete mode 100644 Assets/LuaFramework/Scripts/Framework/Core/Manager.cs delete mode 100644 Assets/LuaFramework/Scripts/Framework/Core/Message.cs delete mode 100644 Assets/LuaFramework/Scripts/Framework/Core/View.cs delete mode 100644 Assets/LuaFramework/Scripts/Manager/GameManager.cs delete mode 100644 Assets/LuaFramework/Scripts/Manager/GameManager.cs.meta delete mode 100644 Assets/LuaFramework/Scripts/Manager/Interface/ITimerBehaviour.cs delete mode 100644 Assets/LuaFramework/Scripts/Manager/Interface/ITimerBehaviour.cs.meta create mode 100644 Assets/LuaFramework/Scripts/Network/HeartBeat.cs rename Assets/LuaFramework/{ToLua/BaseType/UnityEngine_ParticleSystemWrap.cs.meta => Scripts/Network/HeartBeat.cs.meta} (83%) create mode 100644 Assets/LuaFramework/Scripts/Network/ProtoEncrypt.cs rename Assets/{Editor/Utils/PlayerPrefsTools.cs.meta => LuaFramework/Scripts/Network/ProtoEncrypt.cs.meta} (83%) create mode 100644 Assets/LuaFramework/Scripts/Utility/WrapCSObj.cs rename Assets/LuaFramework/{ToLua/BaseType/UnityEngine_LightWrap.cs.meta => Scripts/Utility/WrapCSObj.cs.meta} (83%) delete mode 100644 Assets/LuaFramework/Scripts/View/AppView.cs delete mode 100644 Assets/LuaFramework/ToLua/BaseType/UnityEngine_LightWrap.cs delete mode 100644 Assets/LuaFramework/ToLua/BaseType/UnityEngine_MeshRendererWrap.cs delete mode 100644 Assets/LuaFramework/ToLua/BaseType/UnityEngine_ParticleSystemWrap.cs rename Assets/{Editor/Utils.meta => Scripts/Framework/Common.meta} (77%) rename Assets/{LuaFramework/Luajit/jit.meta => Scripts/Framework/Common/Global.meta} (58%) create mode 100644 Assets/Scripts/Framework/Common/Global/GlobalObjs.cs create mode 100644 Assets/Scripts/Framework/Common/Global/GlobalObjs.cs.meta rename Assets/{LuaFramework/Luajit/Build.bat.meta => Scripts/Framework/Common/Misc.meta} (54%) create mode 100644 Assets/Scripts/Framework/Common/Misc/ObjectParser.cs create mode 100644 Assets/Scripts/Framework/Common/Misc/ObjectParser.cs.meta rename Assets/{LuaFramework/Luajit/luajit.exe.meta => Scripts/Framework/Common/Util.meta} (54%) create mode 100644 Assets/Scripts/Framework/Common/Util/XMLUtil.cs create mode 100644 Assets/Scripts/Framework/Common/Util/XMLUtil.cs.meta create mode 100644 Assets/Scripts/Framework/I18N.meta create mode 100644 Assets/Scripts/Framework/I18N/I18CfgItem.cs create mode 100644 Assets/Scripts/Framework/I18N/I18CfgItem.cs.meta create mode 100644 Assets/Scripts/Framework/I18N/I18N.cs create mode 100644 Assets/Scripts/Framework/I18N/I18N.cs.meta create mode 100644 Assets/Scripts/Framework/Network.meta create mode 100644 Assets/Scripts/Framework/Network/ClientNet.cs create mode 100644 Assets/Scripts/Framework/Network/ClientNet.cs.meta create mode 100644 Assets/Scripts/Framework/Network/INetStateListener.cs create mode 100644 Assets/Scripts/Framework/Network/INetStateListener.cs.meta create mode 100644 Assets/Scripts/Framework/Network/NetDataAnalysis.cs create mode 100644 Assets/Scripts/Framework/Network/NetDataAnalysis.cs.meta create mode 100644 Assets/Scripts/Framework/Network/RemoteConnection.cs create mode 100644 Assets/Scripts/Framework/Network/RemoteConnection.cs.meta create mode 100644 Assets/Scripts/Framework/Network/SocketPackageQueue.cs create mode 100644 Assets/Scripts/Framework/Network/SocketPackageQueue.cs.meta create mode 100644 Assets/Scripts/Framework/Resource/AssetBundleMgr.cs create mode 100644 Assets/Scripts/Framework/Resource/AssetBundleMgr.cs.meta create mode 100644 Assets/Scripts/Framework/Resource/ConfigItem.cs create mode 100644 Assets/Scripts/Framework/Resource/ConfigItem.cs.meta delete mode 100644 Assets/Scripts/Framework/Resource/ResourceCfg.cs delete mode 100644 Assets/Scripts/Framework/Resource/ResourceCfg.cs.meta create mode 100644 Assets/Scripts/Framework/Resource/ResourceConfigItem.cs create mode 100644 Assets/Scripts/Framework/Resource/ResourceConfigItem.cs.meta create mode 100644 Assets/Scripts/Framework/Resource/ResourcePathBuilder.cs create mode 100644 Assets/Scripts/Framework/Resource/ResourcePathBuilder.cs.meta create mode 100644 Assets/Scripts/Framework/SprotoDef.meta create mode 100644 Assets/Scripts/Framework/SprotoDef/c2s.cs rename Assets/{LuaFramework/Scripts/Common/LuaLoader.cs.meta => Scripts/Framework/SprotoDef/c2s.cs.meta} (75%) create mode 100644 Assets/Scripts/Framework/SprotoDef/s2c.cs rename Assets/{LuaFramework/Scripts/View/AppView.cs.meta => Scripts/Framework/SprotoDef/s2c.cs.meta} (75%) create mode 100644 Assets/Scripts/Framework/sproto.meta rename Assets/{LuaFramework/Luajit/jit/dis_mips.lua.meta => Scripts/Framework/sproto/src.meta} (56%) create mode 100644 Assets/Scripts/Framework/sproto/src/SpCodec.cs rename Assets/{LuaFramework/Scripts/Framework/Core/Message.cs.meta => Scripts/Framework/sproto/src/SpCodec.cs.meta} (78%) create mode 100644 Assets/Scripts/Framework/sproto/src/SpDict.cs rename Assets/{LuaFramework/Scripts/Controller/Command/SocketCommand.cs.meta => Scripts/Framework/sproto/src/SpDict.cs.meta} (78%) create mode 100644 Assets/Scripts/Framework/sproto/src/SpField.cs rename Assets/{LuaFramework/Scripts/Framework/Core/View.cs.meta => Scripts/Framework/sproto/src/SpField.cs.meta} (78%) create mode 100644 Assets/Scripts/Framework/sproto/src/SpObject.cs rename Assets/{LuaFramework/Scripts/Framework/Core/Manager.cs.meta => Scripts/Framework/sproto/src/SpObject.cs.meta} (78%) create mode 100644 Assets/Scripts/Framework/sproto/src/SpPacker.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SpPacker.cs.meta create mode 100644 Assets/Scripts/Framework/sproto/src/SpProtoParser.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SpProtoParser.cs.meta create mode 100644 Assets/Scripts/Framework/sproto/src/SpProtocol.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SpProtocol.cs.meta create mode 100644 Assets/Scripts/Framework/sproto/src/SpRpc.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SpRpc.cs.meta create mode 100644 Assets/Scripts/Framework/sproto/src/SpStream.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SpStream.cs.meta create mode 100644 Assets/Scripts/Framework/sproto/src/SpStreamCache.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SpStreamCache.cs.meta create mode 100644 Assets/Scripts/Framework/sproto/src/SpType.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SpType.cs.meta create mode 100644 Assets/Scripts/Framework/sproto/src/SpTypeManager.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SpTypeManager.cs.meta create mode 100644 Assets/Scripts/Framework/sproto/src/SprotoUtil.cs create mode 100644 Assets/Scripts/Framework/sproto/src/SprotoUtil.cs.meta create mode 100644 Assets/Scripts/HOTween.meta rename Assets/{LuaFramework/Scripts/Manager/Interface.meta => Scripts/HOTween/Editor.meta} (63%) create mode 100644 Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll create mode 100644 Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll.mdb rename Assets/{LuaFramework/Luajit/jit/dis_arm.lua.meta => Scripts/HOTween/Editor/HOTweenV1_Editor.dll.mdb.meta} (56%) rename Assets/{LuaFramework/Luajit/lua51.dll.meta => Scripts/HOTween/Editor/HOTweenV1_Editor.dll.meta} (51%) create mode 100644 Assets/Scripts/HOTween/HOTween.XML create mode 100644 Assets/Scripts/HOTween/HOTween.XML.meta create mode 100644 Assets/Scripts/HOTween/HOTween.dll create mode 100644 Assets/Scripts/HOTween/HOTween.dll.mdb rename Assets/{LuaFramework/Luajit/jit/bc.lua.meta => Scripts/HOTween/HOTween.dll.mdb.meta} (56%) create mode 100644 Assets/Scripts/HOTween/HOTween.dll.meta create mode 100644 Assets/Scripts/HOTween/HOTween_License.txt create mode 100644 Assets/Scripts/HOTween/HOTween_License.txt.meta diff --git a/Assets/Editor/Utils/PlayerPrefsTools.cs b/Assets/Editor/Utils/PlayerPrefsTools.cs deleted file mode 100644 index ad34a71..0000000 --- a/Assets/Editor/Utils/PlayerPrefsTools.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; -using UnityEditor; - -public class PlayerPrefsTools -{ - [MenuItem("Tools/ClearCache")] - private static void ClearCache() - { - PlayerPrefs.DeleteAll(); - } -} diff --git a/Assets/GameRes/BaseRes/UpdatePanel.prefab b/Assets/GameRes/BaseRes/UpdatePanel.prefab index 0eccdbe..485fa92 100644 --- a/Assets/GameRes/BaseRes/UpdatePanel.prefab +++ b/Assets/GameRes/BaseRes/UpdatePanel.prefab @@ -30,6 +30,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000796, y: 1.0000796, z: 1.0000796} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8169216279055291532} m_RootOrder: 1 @@ -137,6 +138,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4780904662823820692} m_RootOrder: 0 @@ -213,6 +215,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1716764499801592875} m_RootOrder: 0 @@ -307,6 +310,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000794, y: 1.0000794, z: 1.0000794} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2883265401639076555} m_RootOrder: 2 @@ -400,6 +404,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1819744553754617726} m_RootOrder: 0 @@ -474,6 +479,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 6694990506087024835} - {fileID: 4780904662823820692} @@ -484,8 +490,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0} - m_AnchoredPosition: {x: 0, y: 87.20001} - m_SizeDelta: {x: 1061.6, y: 175.4} + m_AnchoredPosition: {x: -5, y: 87.20001} + m_SizeDelta: {x: 1071.6, y: 175.4} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1109930678617156441 MonoBehaviour: @@ -566,6 +572,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 8671828006783231077} m_Father: {fileID: 2883265401639076555} @@ -642,6 +649,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4164981497408244410} m_RootOrder: 0 @@ -717,6 +725,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 9103090012770035748} m_RootOrder: 0 @@ -796,6 +805,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3407051580043351950} m_RootOrder: 0 @@ -873,6 +883,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000796, y: 1.0000796, z: 1.0000796} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8671828006783231077} m_RootOrder: 1 @@ -980,6 +991,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000796, y: 1.0000796, z: 1.0000796} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1819744553754617726} - {fileID: 4252370615150106047} @@ -1059,6 +1071,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 4164981497408244410} - {fileID: 1716764499801592875} @@ -1174,6 +1187,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 8936710469800839449} m_Father: {fileID: 8169216279055291532} @@ -1294,6 +1308,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 787386967026789516} m_RootOrder: 0 @@ -1372,6 +1387,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.9999204, y: 0.9999204, z: 0.9999204} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 787386967026789516} - {fileID: 5028025846130418035} @@ -1438,6 +1454,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000794, y: 1.0000794, z: 1.0000794} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2883265401639076555} m_RootOrder: 3 @@ -1529,6 +1546,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 2667069267545874327} m_Father: {fileID: 4164981497408244410} @@ -1568,6 +1586,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000795, y: 1.0000795, z: 1.0000795} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 5452845884945931745} m_Father: {fileID: 5603049670005776493} @@ -1688,6 +1707,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000796, y: 1.0000796, z: 1.0000796} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3407051580043351950} - {fileID: 2627341221724831286} @@ -1766,6 +1786,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1819744553754617726} m_RootOrder: 1 @@ -1846,6 +1867,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000795, y: 1.0000795, z: 1.0000795} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3746525588892746467} m_Father: {fileID: 5603049670005776493} @@ -1966,6 +1988,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 866725152063363637} - {fileID: 2770251618636907302} @@ -2043,6 +2066,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5028025846130418035} m_RootOrder: 0 @@ -2123,6 +2147,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000798, y: 1.0000798, z: 1.0000798} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 2888024044834113930} m_Father: {fileID: 2883265401639076555} @@ -2218,6 +2243,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000795, y: 1.0000795, z: 1.0000795} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4164981497408244410} m_RootOrder: 2 @@ -2311,6 +2337,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 8169216279055291532} m_Father: {fileID: 2883265401639076555} @@ -2387,6 +2414,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1751088740464591024} - {fileID: 3944464905748731568} @@ -2465,6 +2493,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1.0000795, y: 1.0000795, z: 1.0000795} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4164981497408244410} m_RootOrder: 3 @@ -2558,6 +2587,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3407051580043351950} m_RootOrder: 1 diff --git a/Assets/LuaFramework/Editor/CustomSettings.cs b/Assets/LuaFramework/Editor/CustomSettings.cs index 414311a..63bf0f4 100644 --- a/Assets/LuaFramework/Editor/CustomSettings.cs +++ b/Assets/LuaFramework/Editor/CustomSettings.cs @@ -6,6 +6,8 @@ using LuaFramework; using UnityEditor; using BindType = ToLuaMenu.BindType; +using Holoville.HOTween; +using Holoville.HOTween.Plugins.Core; using UnityEngine.UI; using System.Reflection; @@ -21,7 +23,7 @@ public static class CustomSettings //导出时强制做为静态类的类型(注意customTypeList 还要添加这个类型才能导出) //unity 有些类作为sealed class, 其实完全等价于静态类 public static List staticClassTypes = new List - { + { typeof(UnityEngine.Application), typeof(UnityEngine.Time), typeof(UnityEngine.Screen), @@ -95,7 +97,13 @@ public static class CustomSettings //_GT(typeof(LineRenderer)) //_GT(typeof(TrailRenderer)) #endif - + + //HOTween + _GT(typeof(HOTween)), + _GT(typeof(Sequence)), + _GT(typeof(Tweener)), + _GT(typeof(PlugColor)), + _GT(typeof(Behaviour)), _GT(typeof(MonoBehaviour)), _GT(typeof(GameObject)), @@ -155,20 +163,17 @@ public static class CustomSettings _GT(typeof(Resources)), _GT(typeof(LuaProfiler)), - //for LuaFramework - _GT(typeof(RectTransform)), + //LuaFramework相关 _GT(typeof(Util)), _GT(typeof(AppConst)), _GT(typeof(LuaHelper)), _GT(typeof(ByteBuffer)), - - _GT(typeof(GameManager)), - _GT(typeof(LuaManager)), - _GT(typeof(NetworkManager)), + _GT(typeof(LuaBehaviour)), _GT(typeof(PlayerPrefs)), // UGUI相关------------------------------------------------------------ + _GT(typeof(RectTransform)), _GT(typeof(Text)), _GT(typeof(Button)), _GT(typeof(Toggle)), @@ -178,13 +183,14 @@ public static class CustomSettings // 自己写的C#脚本------------------------------------------------------------ _GT(typeof(GameLogger)), + _GT(typeof(LogMgr)), _GT(typeof(PanelMgr)), _GT(typeof(ResourceMgr)), _GT(typeof(VersionMgr)), _GT(typeof(BasePanel)), + _GT(typeof(NetworkManager)), _GT(typeof(PrefabObjBinder)), _GT(typeof(AnimationEventTrigger)), - _GT(typeof(LogMgr)), _GT(typeof(EventDispatcher)), _GT(typeof(EventNameDef)), _GT(typeof(ClientSocket)), @@ -218,9 +224,9 @@ public static class CustomSettings //使用方法参见例子14 public static List outList = new List() { - + }; - + //ngui优化,下面的类没有派生类,可以作为sealed class public static List sealedList = new List() { @@ -243,7 +249,7 @@ public static class CustomSettings typeof(UIEventListener), typeof(UIScrollBar), typeof(UICenterOnChild), - typeof(UIScrollView), + typeof(UIScrollView), typeof(UIButton), typeof(UITextList), typeof(UIPlayTween), @@ -270,7 +276,7 @@ public static class CustomSettings public static DelegateType _DT(Type t) { return new DelegateType(t); - } + } [MenuItem("Lua/Attach Profiler", false, 151)] @@ -289,7 +295,7 @@ public static class CustomSettings static void DetachProfiler() { if (!Application.isPlaying) - { + { return; } diff --git a/Assets/LuaFramework/Luajit/Build.bat b/Assets/LuaFramework/Luajit/Build.bat deleted file mode 100644 index 4ea5f3a..0000000 --- a/Assets/LuaFramework/Luajit/Build.bat +++ /dev/null @@ -1,31 +0,0 @@ -@echo off -cd /d %~dp0 - -if not exist dir (mkdir jit) -if not exist Out (mkdir Out) - -xcopy /Y /D ..\..\..\Luajit\jit jit -setlocal enabledelayedexpansion - -for /r %%i in (*.lua) do ( - set v=%%~dpi - call :loop - set v=!v:%~dp0=! - if not exist %~dp0out\!v! (mkdir %~dp0Out\!v!) - ) - -for /r %%i in (*.lua) do ( - set v=%%i - set v=!v:%~dp0=! - call :loop - ..\..\..\Luajit\luajit.exe -b -g !v! Out\!v!.bytes -) - -rd /s/q jit -rd /s/q .\Out\jit\ -setlocal disabledelayedexpansion - -:loop -if "!v:~-1!"==" " set "v=!v:~0,-1!" & goto loop - - diff --git a/Assets/LuaFramework/Luajit/jit/bc.lua b/Assets/LuaFramework/Luajit/jit/bc.lua deleted file mode 100644 index a8cb849..0000000 --- a/Assets/LuaFramework/Luajit/jit/bc.lua +++ /dev/null @@ -1,190 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT bytecode listing module. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- --- This module lists the bytecode of a Lua function. If it's loaded by -jbc --- it hooks into the parser and lists all functions of a chunk as they --- are parsed. --- --- Example usage: --- --- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)' --- luajit -jbc=- foo.lua --- luajit -jbc=foo.list foo.lua --- --- Default output is to stderr. To redirect the output to a file, pass a --- filename as an argument (use '-' for stdout) or set the environment --- variable LUAJIT_LISTFILE. The file is overwritten every time the module --- is started. --- --- This module can also be used programmatically: --- --- local bc = require("jit.bc") --- --- local function foo() print("hello") end --- --- bc.dump(foo) --> -- BYTECODE -- [...] --- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello" --- --- local out = { --- -- Do something with each line: --- write = function(t, ...) io.write(...) end, --- close = function(t) end, --- flush = function(t) end, --- } --- bc.dump(foo, out) --- ------------------------------------------------------------------------------- - --- Cache some library functions and objects. -local jit = require("jit") -assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") -local jutil = require("jit.util") -local vmdef = require("jit.vmdef") -local bit = require("bit") -local sub, gsub, format = string.sub, string.gsub, string.format -local byte, band, shr = string.byte, bit.band, bit.rshift -local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck -local funcuvname = jutil.funcuvname -local bcnames = vmdef.bcnames -local stdout, stderr = io.stdout, io.stderr - ------------------------------------------------------------------------------- - -local function ctlsub(c) - if c == "\n" then return "\\n" - elseif c == "\r" then return "\\r" - elseif c == "\t" then return "\\t" - else return format("\\%03d", byte(c)) - end -end - --- Return one bytecode line. -local function bcline(func, pc, prefix) - local ins, m = funcbc(func, pc) - if not ins then return end - local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128) - local a = band(shr(ins, 8), 0xff) - local oidx = 6*band(ins, 0xff) - local op = sub(bcnames, oidx+1, oidx+6) - local s = format("%04d %s %-6s %3s ", - pc, prefix or " ", op, ma == 0 and "" or a) - local d = shr(ins, 16) - if mc == 13*128 then -- BCMjump - return format("%s=> %04d\n", s, pc+d-0x7fff) - end - if mb ~= 0 then - d = band(d, 0xff) - elseif mc == 0 then - return s.."\n" - end - local kc - if mc == 10*128 then -- BCMstr - kc = funck(func, -d-1) - kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub)) - elseif mc == 9*128 then -- BCMnum - kc = funck(func, d) - if op == "TSETM " then kc = kc - 2^52 end - elseif mc == 12*128 then -- BCMfunc - local fi = funcinfo(funck(func, -d-1)) - if fi.ffid then - kc = vmdef.ffnames[fi.ffid] - else - kc = fi.loc - end - elseif mc == 5*128 then -- BCMuv - kc = funcuvname(func, d) - end - if ma == 5 then -- BCMuv - local ka = funcuvname(func, a) - if kc then kc = ka.." ; "..kc else kc = ka end - end - if mb ~= 0 then - local b = shr(ins, 24) - if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end - return format("%s%3d %3d\n", s, b, d) - end - if kc then return format("%s%3d ; %s\n", s, d, kc) end - if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits - return format("%s%3d\n", s, d) -end - --- Collect branch targets of a function. -local function bctargets(func) - local target = {} - for pc=1,1000000000 do - local ins, m = funcbc(func, pc) - if not ins then break end - if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end - end - return target -end - --- Dump bytecode instructions of a function. -local function bcdump(func, out, all) - if not out then out = stdout end - local fi = funcinfo(func) - if all and fi.children then - for n=-1,-1000000000,-1 do - local k = funck(func, n) - if not k then break end - if type(k) == "proto" then bcdump(k, out, true) end - end - end - out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined)) - local target = bctargets(func) - for pc=1,1000000000 do - local s = bcline(func, pc, target[pc] and "=>") - if not s then break end - out:write(s) - end - out:write("\n") - out:flush() -end - ------------------------------------------------------------------------------- - --- Active flag and output file handle. -local active, out - --- List handler. -local function h_list(func) - return bcdump(func, out) -end - --- Detach list handler. -local function bclistoff() - if active then - active = false - jit.attach(h_list) - if out and out ~= stdout and out ~= stderr then out:close() end - out = nil - end -end - --- Open the output file and attach list handler. -local function bcliston(outfile) - if active then bclistoff() end - if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end - if outfile then - out = outfile == "-" and stdout or assert(io.open(outfile, "w")) - else - out = stderr - end - jit.attach(h_list, "bc") - active = true -end - --- Public module functions. -return { - line = bcline, - dump = bcdump, - targets = bctargets, - on = bcliston, - off = bclistoff, - start = bcliston -- For -j command line option. -} - diff --git a/Assets/LuaFramework/Luajit/jit/bcsave.lua b/Assets/LuaFramework/Luajit/jit/bcsave.lua deleted file mode 100644 index d0968b1..0000000 --- a/Assets/LuaFramework/Luajit/jit/bcsave.lua +++ /dev/null @@ -1,661 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT module to save/list bytecode. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- --- This module saves or lists the bytecode for an input file. --- It's run by the -b command line option. --- ------------------------------------------------------------------------------- - -local jit = require("jit") -assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") -local bit = require("bit") - --- Symbol name prefix for LuaJIT bytecode. -local LJBC_PREFIX = "luaJIT_BC_" - ------------------------------------------------------------------------------- - -local function usage() - io.stderr:write[[ -Save LuaJIT bytecode: luajit -b[options] input output - -l Only list bytecode. - -s Strip debug info (default). - -g Keep debug info. - -n name Set module name (default: auto-detect from input name). - -t type Set output file type (default: auto-detect from output name). - -a arch Override architecture for object files (default: native). - -o os Override OS for object files (default: native). - -e chunk Use chunk string as input. - -- Stop handling options. - - Use stdin as input and/or stdout as output. - -File types: c h obj o raw (default) -]] - os.exit(1) -end - -local function check(ok, ...) - if ok then return ok, ... end - io.stderr:write("luajit: ", ...) - io.stderr:write("\n") - os.exit(1) -end - -local function readfile(input) - if type(input) == "function" then return input end - if input == "-" then input = nil end - return check(loadfile(input)) -end - -local function savefile(name, mode) - if name == "-" then return io.stdout end - return check(io.open(name, mode)) -end - ------------------------------------------------------------------------------- - -local map_type = { - raw = "raw", c = "c", h = "h", o = "obj", obj = "obj", -} - -local map_arch = { - x86 = true, x64 = true, arm = true, arm64 = true, ppc = true, - mips = true, mipsel = true, -} - -local map_os = { - linux = true, windows = true, osx = true, freebsd = true, netbsd = true, - openbsd = true, dragonfly = true, solaris = true, -} - -local function checkarg(str, map, err) - str = string.lower(str) - local s = check(map[str], "unknown ", err) - return s == true and str or s -end - -local function detecttype(str) - local ext = string.match(string.lower(str), "%.(%a+)$") - return map_type[ext] or "raw" -end - -local function checkmodname(str) - check(string.match(str, "^[%w_.%-]+$"), "bad module name") - return string.gsub(str, "[%.%-]", "_") -end - -local function detectmodname(str) - if type(str) == "string" then - local tail = string.match(str, "[^/\\]+$") - if tail then str = tail end - local head = string.match(str, "^(.*)%.[^.]*$") - if head then str = head end - str = string.match(str, "^[%w_.%-]+") - else - str = nil - end - check(str, "cannot derive module name, use -n name") - return string.gsub(str, "[%.%-]", "_") -end - ------------------------------------------------------------------------------- - -local function bcsave_tail(fp, output, s) - local ok, err = fp:write(s) - if ok and output ~= "-" then ok, err = fp:close() end - check(ok, "cannot write ", output, ": ", err) -end - -local function bcsave_raw(output, s) - local fp = savefile(output, "wb") - bcsave_tail(fp, output, s) -end - -local function bcsave_c(ctx, output, s) - local fp = savefile(output, "w") - if ctx.type == "c" then - fp:write(string.format([[ -#ifdef _cplusplus -extern "C" -#endif -#ifdef _WIN32 -__declspec(dllexport) -#endif -const char %s%s[] = { -]], LJBC_PREFIX, ctx.modname)) - else - fp:write(string.format([[ -#define %s%s_SIZE %d -static const char %s%s[] = { -]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname)) - end - local t, n, m = {}, 0, 0 - for i=1,#s do - local b = tostring(string.byte(s, i)) - m = m + #b + 1 - if m > 78 then - fp:write(table.concat(t, ",", 1, n), ",\n") - n, m = 0, #b + 1 - end - n = n + 1 - t[n] = b - end - bcsave_tail(fp, output, table.concat(t, ",", 1, n).."\n};\n") -end - -local function bcsave_elfobj(ctx, output, s, ffi) - ffi.cdef[[ -typedef struct { - uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7]; - uint16_t type, machine; - uint32_t version; - uint32_t entry, phofs, shofs; - uint32_t flags; - uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; -} ELF32header; -typedef struct { - uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7]; - uint16_t type, machine; - uint32_t version; - uint64_t entry, phofs, shofs; - uint32_t flags; - uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; -} ELF64header; -typedef struct { - uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize; -} ELF32sectheader; -typedef struct { - uint32_t name, type; - uint64_t flags, addr, ofs, size; - uint32_t link, info; - uint64_t align, entsize; -} ELF64sectheader; -typedef struct { - uint32_t name, value, size; - uint8_t info, other; - uint16_t sectidx; -} ELF32symbol; -typedef struct { - uint32_t name; - uint8_t info, other; - uint16_t sectidx; - uint64_t value, size; -} ELF64symbol; -typedef struct { - ELF32header hdr; - ELF32sectheader sect[6]; - ELF32symbol sym[2]; - uint8_t space[4096]; -} ELF32obj; -typedef struct { - ELF64header hdr; - ELF64sectheader sect[6]; - ELF64symbol sym[2]; - uint8_t space[4096]; -} ELF64obj; -]] - local symname = LJBC_PREFIX..ctx.modname - local is64, isbe = false, false - if ctx.arch == "x64" or ctx.arch == "arm64" then - is64 = true - elseif ctx.arch == "ppc" or ctx.arch == "mips" then - isbe = true - end - - -- Handle different host/target endianess. - local function f32(x) return x end - local f16, fofs = f32, f32 - if ffi.abi("be") ~= isbe then - f32 = bit.bswap - function f16(x) return bit.rshift(bit.bswap(x), 16) end - if is64 then - local two32 = ffi.cast("int64_t", 2^32) - function fofs(x) return bit.bswap(x)*two32 end - else - fofs = f32 - end - end - - -- Create ELF object and fill in header. - local o = ffi.new(is64 and "ELF64obj" or "ELF32obj") - local hdr = o.hdr - if ctx.os == "bsd" or ctx.os == "other" then -- Determine native hdr.eosabi. - local bf = assert(io.open("/bin/ls", "rb")) - local bs = bf:read(9) - bf:close() - ffi.copy(o, bs, 9) - check(hdr.emagic[0] == 127, "no support for writing native object files") - else - hdr.emagic = "\127ELF" - hdr.eosabi = ({ freebsd=9, netbsd=2, openbsd=12, solaris=6 })[ctx.os] or 0 - end - hdr.eclass = is64 and 2 or 1 - hdr.eendian = isbe and 2 or 1 - hdr.eversion = 1 - hdr.type = f16(1) - hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, ppc=20, mips=8, mipsel=8 })[ctx.arch]) - if ctx.arch == "mips" or ctx.arch == "mipsel" then - hdr.flags = 0x50001006 - end - hdr.version = f32(1) - hdr.shofs = fofs(ffi.offsetof(o, "sect")) - hdr.ehsize = f16(ffi.sizeof(hdr)) - hdr.shentsize = f16(ffi.sizeof(o.sect[0])) - hdr.shnum = f16(6) - hdr.shstridx = f16(2) - - -- Fill in sections and symbols. - local sofs, ofs = ffi.offsetof(o, "space"), 1 - for i,name in ipairs{ - ".symtab", ".shstrtab", ".strtab", ".rodata", ".note.GNU-stack", - } do - local sect = o.sect[i] - sect.align = fofs(1) - sect.name = f32(ofs) - ffi.copy(o.space+ofs, name) - ofs = ofs + #name+1 - end - o.sect[1].type = f32(2) -- .symtab - o.sect[1].link = f32(3) - o.sect[1].info = f32(1) - o.sect[1].align = fofs(8) - o.sect[1].ofs = fofs(ffi.offsetof(o, "sym")) - o.sect[1].entsize = fofs(ffi.sizeof(o.sym[0])) - o.sect[1].size = fofs(ffi.sizeof(o.sym)) - o.sym[1].name = f32(1) - o.sym[1].sectidx = f16(4) - o.sym[1].size = fofs(#s) - o.sym[1].info = 17 - o.sect[2].type = f32(3) -- .shstrtab - o.sect[2].ofs = fofs(sofs) - o.sect[2].size = fofs(ofs) - o.sect[3].type = f32(3) -- .strtab - o.sect[3].ofs = fofs(sofs + ofs) - o.sect[3].size = fofs(#symname+1) - ffi.copy(o.space+ofs+1, symname) - ofs = ofs + #symname + 2 - o.sect[4].type = f32(1) -- .rodata - o.sect[4].flags = fofs(2) - o.sect[4].ofs = fofs(sofs + ofs) - o.sect[4].size = fofs(#s) - o.sect[5].type = f32(1) -- .note.GNU-stack - o.sect[5].ofs = fofs(sofs + ofs + #s) - - -- Write ELF object file. - local fp = savefile(output, "wb") - fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs)) - bcsave_tail(fp, output, s) -end - -local function bcsave_peobj(ctx, output, s, ffi) - ffi.cdef[[ -typedef struct { - uint16_t arch, nsects; - uint32_t time, symtabofs, nsyms; - uint16_t opthdrsz, flags; -} PEheader; -typedef struct { - char name[8]; - uint32_t vsize, vaddr, size, ofs, relocofs, lineofs; - uint16_t nreloc, nline; - uint32_t flags; -} PEsection; -typedef struct __attribute((packed)) { - union { - char name[8]; - uint32_t nameref[2]; - }; - uint32_t value; - int16_t sect; - uint16_t type; - uint8_t scl, naux; -} PEsym; -typedef struct __attribute((packed)) { - uint32_t size; - uint16_t nreloc, nline; - uint32_t cksum; - uint16_t assoc; - uint8_t comdatsel, unused[3]; -} PEsymaux; -typedef struct { - PEheader hdr; - PEsection sect[2]; - // Must be an even number of symbol structs. - PEsym sym0; - PEsymaux sym0aux; - PEsym sym1; - PEsymaux sym1aux; - PEsym sym2; - PEsym sym3; - uint32_t strtabsize; - uint8_t space[4096]; -} PEobj; -]] - local symname = LJBC_PREFIX..ctx.modname - local is64 = false - if ctx.arch == "x86" then - symname = "_"..symname - elseif ctx.arch == "x64" then - is64 = true - end - local symexport = " /EXPORT:"..symname..",DATA " - - -- The file format is always little-endian. Swap if the host is big-endian. - local function f32(x) return x end - local f16 = f32 - if ffi.abi("be") then - f32 = bit.bswap - function f16(x) return bit.rshift(bit.bswap(x), 16) end - end - - -- Create PE object and fill in header. - local o = ffi.new("PEobj") - local hdr = o.hdr - hdr.arch = f16(({ x86=0x14c, x64=0x8664, arm=0x1c0, ppc=0x1f2, mips=0x366, mipsel=0x366 })[ctx.arch]) - hdr.nsects = f16(2) - hdr.symtabofs = f32(ffi.offsetof(o, "sym0")) - hdr.nsyms = f32(6) - - -- Fill in sections and symbols. - o.sect[0].name = ".drectve" - o.sect[0].size = f32(#symexport) - o.sect[0].flags = f32(0x00100a00) - o.sym0.sect = f16(1) - o.sym0.scl = 3 - o.sym0.name = ".drectve" - o.sym0.naux = 1 - o.sym0aux.size = f32(#symexport) - o.sect[1].name = ".rdata" - o.sect[1].size = f32(#s) - o.sect[1].flags = f32(0x40300040) - o.sym1.sect = f16(2) - o.sym1.scl = 3 - o.sym1.name = ".rdata" - o.sym1.naux = 1 - o.sym1aux.size = f32(#s) - o.sym2.sect = f16(2) - o.sym2.scl = 2 - o.sym2.nameref[1] = f32(4) - o.sym3.sect = f16(-1) - o.sym3.scl = 2 - o.sym3.value = f32(1) - o.sym3.name = "@feat.00" -- Mark as SafeSEH compliant. - ffi.copy(o.space, symname) - local ofs = #symname + 1 - o.strtabsize = f32(ofs + 4) - o.sect[0].ofs = f32(ffi.offsetof(o, "space") + ofs) - ffi.copy(o.space + ofs, symexport) - ofs = ofs + #symexport - o.sect[1].ofs = f32(ffi.offsetof(o, "space") + ofs) - - -- Write PE object file. - local fp = savefile(output, "wb") - fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs)) - bcsave_tail(fp, output, s) -end - -local function bcsave_machobj(ctx, output, s, ffi) - ffi.cdef[[ -typedef struct -{ - uint32_t magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags; -} mach_header; -typedef struct -{ - mach_header; uint32_t reserved; -} mach_header_64; -typedef struct { - uint32_t cmd, cmdsize; - char segname[16]; - uint32_t vmaddr, vmsize, fileoff, filesize; - uint32_t maxprot, initprot, nsects, flags; -} mach_segment_command; -typedef struct { - uint32_t cmd, cmdsize; - char segname[16]; - uint64_t vmaddr, vmsize, fileoff, filesize; - uint32_t maxprot, initprot, nsects, flags; -} mach_segment_command_64; -typedef struct { - char sectname[16], segname[16]; - uint32_t addr, size; - uint32_t offset, align, reloff, nreloc, flags; - uint32_t reserved1, reserved2; -} mach_section; -typedef struct { - char sectname[16], segname[16]; - uint64_t addr, size; - uint32_t offset, align, reloff, nreloc, flags; - uint32_t reserved1, reserved2, reserved3; -} mach_section_64; -typedef struct { - uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize; -} mach_symtab_command; -typedef struct { - int32_t strx; - uint8_t type, sect; - int16_t desc; - uint32_t value; -} mach_nlist; -typedef struct { - uint32_t strx; - uint8_t type, sect; - uint16_t desc; - uint64_t value; -} mach_nlist_64; -typedef struct -{ - uint32_t magic, nfat_arch; -} mach_fat_header; -typedef struct -{ - uint32_t cputype, cpusubtype, offset, size, align; -} mach_fat_arch; -typedef struct { - struct { - mach_header hdr; - mach_segment_command seg; - mach_section sec; - mach_symtab_command sym; - } arch[1]; - mach_nlist sym_entry; - uint8_t space[4096]; -} mach_obj; -typedef struct { - struct { - mach_header_64 hdr; - mach_segment_command_64 seg; - mach_section_64 sec; - mach_symtab_command sym; - } arch[1]; - mach_nlist_64 sym_entry; - uint8_t space[4096]; -} mach_obj_64; -typedef struct { - mach_fat_header fat; - mach_fat_arch fat_arch[2]; - struct { - mach_header hdr; - mach_segment_command seg; - mach_section sec; - mach_symtab_command sym; - } arch[2]; - mach_nlist sym_entry; - uint8_t space[4096]; -} mach_fat_obj; -]] - local symname = '_'..LJBC_PREFIX..ctx.modname - local isfat, is64, align, mobj = false, false, 4, "mach_obj" - if ctx.arch == "x64" then - is64, align, mobj = true, 8, "mach_obj_64" - elseif ctx.arch == "arm" then - isfat, mobj = true, "mach_fat_obj" - elseif ctx.arch == "arm64" then - is64, align, isfat, mobj = true, 8, true, "mach_fat_obj" - else - check(ctx.arch == "x86", "unsupported architecture for OSX") - end - local function aligned(v, a) return bit.band(v+a-1, -a) end - local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE. - - -- Create Mach-O object and fill in header. - local o = ffi.new(mobj) - local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align) - local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch] - local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch] - if isfat then - o.fat.magic = be32(0xcafebabe) - o.fat.nfat_arch = be32(#cpusubtype) - end - - -- Fill in sections and symbols. - for i=0,#cpusubtype-1 do - local ofs = 0 - if isfat then - local a = o.fat_arch[i] - a.cputype = be32(cputype[i+1]) - a.cpusubtype = be32(cpusubtype[i+1]) - -- Subsequent slices overlap each other to share data. - ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0]) - a.offset = be32(ofs) - a.size = be32(mach_size-ofs+#s) - end - local a = o.arch[i] - a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface - a.hdr.cputype = cputype[i+1] - a.hdr.cpusubtype = cpusubtype[i+1] - a.hdr.filetype = 1 - a.hdr.ncmds = 2 - a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym) - a.seg.cmd = is64 and 0x19 or 0x1 - a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec) - a.seg.vmsize = #s - a.seg.fileoff = mach_size-ofs - a.seg.filesize = #s - a.seg.maxprot = 1 - a.seg.initprot = 1 - a.seg.nsects = 1 - ffi.copy(a.sec.sectname, "__data") - ffi.copy(a.sec.segname, "__DATA") - a.sec.size = #s - a.sec.offset = mach_size-ofs - a.sym.cmd = 2 - a.sym.cmdsize = ffi.sizeof(a.sym) - a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs - a.sym.nsyms = 1 - a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs - a.sym.strsize = aligned(#symname+2, align) - end - o.sym_entry.type = 0xf - o.sym_entry.sect = 1 - o.sym_entry.strx = 1 - ffi.copy(o.space+1, symname) - - -- Write Macho-O object file. - local fp = savefile(output, "wb") - fp:write(ffi.string(o, mach_size)) - bcsave_tail(fp, output, s) -end - -local function bcsave_obj(ctx, output, s) - local ok, ffi = pcall(require, "ffi") - check(ok, "FFI library required to write this file type") - if ctx.os == "windows" then - return bcsave_peobj(ctx, output, s, ffi) - elseif ctx.os == "osx" then - return bcsave_machobj(ctx, output, s, ffi) - else - return bcsave_elfobj(ctx, output, s, ffi) - end -end - ------------------------------------------------------------------------------- - -local function bclist(input, output) - local f = readfile(input) - require("jit.bc").dump(f, savefile(output, "w"), true) -end - -local function bcsave(ctx, input, output) - local f = readfile(input) - local s = string.dump(f, ctx.strip) - local t = ctx.type - if not t then - t = detecttype(output) - ctx.type = t - end - if t == "raw" then - bcsave_raw(output, s) - else - if not ctx.modname then ctx.modname = detectmodname(input) end - if t == "obj" then - bcsave_obj(ctx, output, s) - else - bcsave_c(ctx, output, s) - end - end -end - -local function docmd(...) - local arg = {...} - local n = 1 - local list = false - local ctx = { - strip = true, arch = jit.arch, os = string.lower(jit.os), - type = false, modname = false, - } - while n <= #arg do - local a = arg[n] - if type(a) == "string" and string.sub(a, 1, 1) == "-" and a ~= "-" then - table.remove(arg, n) - if a == "--" then break end - for m=2,#a do - local opt = string.sub(a, m, m) - if opt == "l" then - list = true - elseif opt == "s" then - ctx.strip = true - elseif opt == "g" then - ctx.strip = false - else - if arg[n] == nil or m ~= #a then usage() end - if opt == "e" then - if n ~= 1 then usage() end - arg[1] = check(loadstring(arg[1])) - elseif opt == "n" then - ctx.modname = checkmodname(table.remove(arg, n)) - elseif opt == "t" then - ctx.type = checkarg(table.remove(arg, n), map_type, "file type") - elseif opt == "a" then - ctx.arch = checkarg(table.remove(arg, n), map_arch, "architecture") - elseif opt == "o" then - ctx.os = checkarg(table.remove(arg, n), map_os, "OS name") - else - usage() - end - end - end - else - n = n + 1 - end - end - if list then - if #arg == 0 or #arg > 2 then usage() end - bclist(arg[1], arg[2] or "-") - else - if #arg ~= 2 then usage() end - bcsave(ctx, arg[1], arg[2]) - end -end - ------------------------------------------------------------------------------- - --- Public module functions. -return { - start = docmd -- Process -b command line option. -} - diff --git a/Assets/LuaFramework/Luajit/jit/bcsave.lua.meta b/Assets/LuaFramework/Luajit/jit/bcsave.lua.meta deleted file mode 100644 index ca4e305..0000000 --- a/Assets/LuaFramework/Luajit/jit/bcsave.lua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 9cb37ebfedf93ae4b96e0da0d77065c4 -DefaultImporter: - userData: diff --git a/Assets/LuaFramework/Luajit/jit/dis_arm.lua b/Assets/LuaFramework/Luajit/jit/dis_arm.lua deleted file mode 100644 index 1296d81..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_arm.lua +++ /dev/null @@ -1,689 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT ARM disassembler module. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- This is a helper module used by the LuaJIT machine code dumper module. --- --- It disassembles most user-mode ARMv7 instructions --- NYI: Advanced SIMD and VFP instructions. ------------------------------------------------------------------------------- - -local type = type -local sub, byte, format = string.sub, string.byte, string.format -local match, gmatch, gsub = string.match, string.gmatch, string.gsub -local concat = table.concat -local bit = require("bit") -local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex -local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift - ------------------------------------------------------------------------------- --- Opcode maps ------------------------------------------------------------------------------- - -local map_loadc = { - shift = 8, mask = 15, - [10] = { - shift = 20, mask = 1, - [0] = { - shift = 23, mask = 3, - [0] = "vmovFmDN", "vstmFNdr", - _ = { - shift = 21, mask = 1, - [0] = "vstrFdl", - { shift = 16, mask = 15, [13] = "vpushFdr", _ = "vstmdbFNdr", } - }, - }, - { - shift = 23, mask = 3, - [0] = "vmovFDNm", - { shift = 16, mask = 15, [13] = "vpopFdr", _ = "vldmFNdr", }, - _ = { - shift = 21, mask = 1, - [0] = "vldrFdl", "vldmdbFNdr", - }, - }, - }, - [11] = { - shift = 20, mask = 1, - [0] = { - shift = 23, mask = 3, - [0] = "vmovGmDN", "vstmGNdr", - _ = { - shift = 21, mask = 1, - [0] = "vstrGdl", - { shift = 16, mask = 15, [13] = "vpushGdr", _ = "vstmdbGNdr", } - }, - }, - { - shift = 23, mask = 3, - [0] = "vmovGDNm", - { shift = 16, mask = 15, [13] = "vpopGdr", _ = "vldmGNdr", }, - _ = { - shift = 21, mask = 1, - [0] = "vldrGdl", "vldmdbGNdr", - }, - }, - }, - _ = { - shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc. - }, -} - -local map_vfps = { - shift = 6, mask = 0x2c001, - [0] = "vmlaF.dnm", "vmlsF.dnm", - [0x04000] = "vnmlsF.dnm", [0x04001] = "vnmlaF.dnm", - [0x08000] = "vmulF.dnm", [0x08001] = "vnmulF.dnm", - [0x0c000] = "vaddF.dnm", [0x0c001] = "vsubF.dnm", - [0x20000] = "vdivF.dnm", - [0x24000] = "vfnmsF.dnm", [0x24001] = "vfnmaF.dnm", - [0x28000] = "vfmaF.dnm", [0x28001] = "vfmsF.dnm", - [0x2c000] = "vmovF.dY", - [0x2c001] = { - shift = 7, mask = 0x1e01, - [0] = "vmovF.dm", "vabsF.dm", - [0x0200] = "vnegF.dm", [0x0201] = "vsqrtF.dm", - [0x0800] = "vcmpF.dm", [0x0801] = "vcmpeF.dm", - [0x0a00] = "vcmpzF.d", [0x0a01] = "vcmpzeF.d", - [0x0e01] = "vcvtG.dF.m", - [0x1000] = "vcvt.f32.u32Fdm", [0x1001] = "vcvt.f32.s32Fdm", - [0x1800] = "vcvtr.u32F.dm", [0x1801] = "vcvt.u32F.dm", - [0x1a00] = "vcvtr.s32F.dm", [0x1a01] = "vcvt.s32F.dm", - }, -} - -local map_vfpd = { - shift = 6, mask = 0x2c001, - [0] = "vmlaG.dnm", "vmlsG.dnm", - [0x04000] = "vnmlsG.dnm", [0x04001] = "vnmlaG.dnm", - [0x08000] = "vmulG.dnm", [0x08001] = "vnmulG.dnm", - [0x0c000] = "vaddG.dnm", [0x0c001] = "vsubG.dnm", - [0x20000] = "vdivG.dnm", - [0x24000] = "vfnmsG.dnm", [0x24001] = "vfnmaG.dnm", - [0x28000] = "vfmaG.dnm", [0x28001] = "vfmsG.dnm", - [0x2c000] = "vmovG.dY", - [0x2c001] = { - shift = 7, mask = 0x1e01, - [0] = "vmovG.dm", "vabsG.dm", - [0x0200] = "vnegG.dm", [0x0201] = "vsqrtG.dm", - [0x0800] = "vcmpG.dm", [0x0801] = "vcmpeG.dm", - [0x0a00] = "vcmpzG.d", [0x0a01] = "vcmpzeG.d", - [0x0e01] = "vcvtF.dG.m", - [0x1000] = "vcvt.f64.u32GdFm", [0x1001] = "vcvt.f64.s32GdFm", - [0x1800] = "vcvtr.u32FdG.m", [0x1801] = "vcvt.u32FdG.m", - [0x1a00] = "vcvtr.s32FdG.m", [0x1a01] = "vcvt.s32FdG.m", - }, -} - -local map_datac = { - shift = 24, mask = 1, - [0] = { - shift = 4, mask = 1, - [0] = { - shift = 8, mask = 15, - [10] = map_vfps, - [11] = map_vfpd, - -- NYI cdp, mcr, mrc. - }, - { - shift = 8, mask = 15, - [10] = { - shift = 20, mask = 15, - [0] = "vmovFnD", "vmovFDn", - [14] = "vmsrD", - [15] = { shift = 12, mask = 15, [15] = "vmrs", _ = "vmrsD", }, - }, - }, - }, - "svcT", -} - -local map_loadcu = { - shift = 0, mask = 0, -- NYI unconditional CP load/store. -} - -local map_datacu = { - shift = 0, mask = 0, -- NYI unconditional CP data. -} - -local map_simddata = { - shift = 0, mask = 0, -- NYI SIMD data. -} - -local map_simdload = { - shift = 0, mask = 0, -- NYI SIMD load/store, preload. -} - -local map_preload = { - shift = 0, mask = 0, -- NYI preload. -} - -local map_media = { - shift = 20, mask = 31, - [0] = false, - { --01 - shift = 5, mask = 7, - [0] = "sadd16DNM", "sasxDNM", "ssaxDNM", "ssub16DNM", - "sadd8DNM", false, false, "ssub8DNM", - }, - { --02 - shift = 5, mask = 7, - [0] = "qadd16DNM", "qasxDNM", "qsaxDNM", "qsub16DNM", - "qadd8DNM", false, false, "qsub8DNM", - }, - { --03 - shift = 5, mask = 7, - [0] = "shadd16DNM", "shasxDNM", "shsaxDNM", "shsub16DNM", - "shadd8DNM", false, false, "shsub8DNM", - }, - false, - { --05 - shift = 5, mask = 7, - [0] = "uadd16DNM", "uasxDNM", "usaxDNM", "usub16DNM", - "uadd8DNM", false, false, "usub8DNM", - }, - { --06 - shift = 5, mask = 7, - [0] = "uqadd16DNM", "uqasxDNM", "uqsaxDNM", "uqsub16DNM", - "uqadd8DNM", false, false, "uqsub8DNM", - }, - { --07 - shift = 5, mask = 7, - [0] = "uhadd16DNM", "uhasxDNM", "uhsaxDNM", "uhsub16DNM", - "uhadd8DNM", false, false, "uhsub8DNM", - }, - { --08 - shift = 5, mask = 7, - [0] = "pkhbtDNMU", false, "pkhtbDNMU", - { shift = 16, mask = 15, [15] = "sxtb16DMU", _ = "sxtab16DNMU", }, - "pkhbtDNMU", "selDNM", "pkhtbDNMU", - }, - false, - { --0a - shift = 5, mask = 7, - [0] = "ssatDxMu", "ssat16DxM", "ssatDxMu", - { shift = 16, mask = 15, [15] = "sxtbDMU", _ = "sxtabDNMU", }, - "ssatDxMu", false, "ssatDxMu", - }, - { --0b - shift = 5, mask = 7, - [0] = "ssatDxMu", "revDM", "ssatDxMu", - { shift = 16, mask = 15, [15] = "sxthDMU", _ = "sxtahDNMU", }, - "ssatDxMu", "rev16DM", "ssatDxMu", - }, - { --0c - shift = 5, mask = 7, - [3] = { shift = 16, mask = 15, [15] = "uxtb16DMU", _ = "uxtab16DNMU", }, - }, - false, - { --0e - shift = 5, mask = 7, - [0] = "usatDwMu", "usat16DwM", "usatDwMu", - { shift = 16, mask = 15, [15] = "uxtbDMU", _ = "uxtabDNMU", }, - "usatDwMu", false, "usatDwMu", - }, - { --0f - shift = 5, mask = 7, - [0] = "usatDwMu", "rbitDM", "usatDwMu", - { shift = 16, mask = 15, [15] = "uxthDMU", _ = "uxtahDNMU", }, - "usatDwMu", "revshDM", "usatDwMu", - }, - { --10 - shift = 12, mask = 15, - [15] = { - shift = 5, mask = 7, - "smuadNMS", "smuadxNMS", "smusdNMS", "smusdxNMS", - }, - _ = { - shift = 5, mask = 7, - [0] = "smladNMSD", "smladxNMSD", "smlsdNMSD", "smlsdxNMSD", - }, - }, - false, false, false, - { --14 - shift = 5, mask = 7, - [0] = "smlaldDNMS", "smlaldxDNMS", "smlsldDNMS", "smlsldxDNMS", - }, - { --15 - shift = 5, mask = 7, - [0] = { shift = 12, mask = 15, [15] = "smmulNMS", _ = "smmlaNMSD", }, - { shift = 12, mask = 15, [15] = "smmulrNMS", _ = "smmlarNMSD", }, - false, false, false, false, - "smmlsNMSD", "smmlsrNMSD", - }, - false, false, - { --18 - shift = 5, mask = 7, - [0] = { shift = 12, mask = 15, [15] = "usad8NMS", _ = "usada8NMSD", }, - }, - false, - { --1a - shift = 5, mask = 3, [2] = "sbfxDMvw", - }, - { --1b - shift = 5, mask = 3, [2] = "sbfxDMvw", - }, - { --1c - shift = 5, mask = 3, - [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", }, - }, - { --1d - shift = 5, mask = 3, - [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", }, - }, - { --1e - shift = 5, mask = 3, [2] = "ubfxDMvw", - }, - { --1f - shift = 5, mask = 3, [2] = "ubfxDMvw", - }, -} - -local map_load = { - shift = 21, mask = 9, - { - shift = 20, mask = 5, - [0] = "strtDL", "ldrtDL", [4] = "strbtDL", [5] = "ldrbtDL", - }, - _ = { - shift = 20, mask = 5, - [0] = "strDL", "ldrDL", [4] = "strbDL", [5] = "ldrbDL", - } -} - -local map_load1 = { - shift = 4, mask = 1, - [0] = map_load, map_media, -} - -local map_loadm = { - shift = 20, mask = 1, - [0] = { - shift = 23, mask = 3, - [0] = "stmdaNR", "stmNR", - { shift = 16, mask = 63, [45] = "pushR", _ = "stmdbNR", }, "stmibNR", - }, - { - shift = 23, mask = 3, - [0] = "ldmdaNR", { shift = 16, mask = 63, [61] = "popR", _ = "ldmNR", }, - "ldmdbNR", "ldmibNR", - }, -} - -local map_data = { - shift = 21, mask = 15, - [0] = "andDNPs", "eorDNPs", "subDNPs", "rsbDNPs", - "addDNPs", "adcDNPs", "sbcDNPs", "rscDNPs", - "tstNP", "teqNP", "cmpNP", "cmnNP", - "orrDNPs", "movDPs", "bicDNPs", "mvnDPs", -} - -local map_mul = { - shift = 21, mask = 7, - [0] = "mulNMSs", "mlaNMSDs", "umaalDNMS", "mlsDNMS", - "umullDNMSs", "umlalDNMSs", "smullDNMSs", "smlalDNMSs", -} - -local map_sync = { - shift = 20, mask = 15, -- NYI: brackets around N. R(D+1) for ldrexd/strexd. - [0] = "swpDMN", false, false, false, - "swpbDMN", false, false, false, - "strexDMN", "ldrexDN", "strexdDN", "ldrexdDN", - "strexbDMN", "ldrexbDN", "strexhDN", "ldrexhDN", -} - -local map_mulh = { - shift = 21, mask = 3, - [0] = { shift = 5, mask = 3, - [0] = "smlabbNMSD", "smlatbNMSD", "smlabtNMSD", "smlattNMSD", }, - { shift = 5, mask = 3, - [0] = "smlawbNMSD", "smulwbNMS", "smlawtNMSD", "smulwtNMS", }, - { shift = 5, mask = 3, - [0] = "smlalbbDNMS", "smlaltbDNMS", "smlalbtDNMS", "smlalttDNMS", }, - { shift = 5, mask = 3, - [0] = "smulbbNMS", "smultbNMS", "smulbtNMS", "smulttNMS", }, -} - -local map_misc = { - shift = 4, mask = 7, - -- NYI: decode PSR bits of msr. - [0] = { shift = 21, mask = 1, [0] = "mrsD", "msrM", }, - { shift = 21, mask = 3, "bxM", false, "clzDM", }, - { shift = 21, mask = 3, "bxjM", }, - { shift = 21, mask = 3, "blxM", }, - false, - { shift = 21, mask = 3, [0] = "qaddDMN", "qsubDMN", "qdaddDMN", "qdsubDMN", }, - false, - { shift = 21, mask = 3, "bkptK", }, -} - -local map_datar = { - shift = 4, mask = 9, - [9] = { - shift = 5, mask = 3, - [0] = { shift = 24, mask = 1, [0] = map_mul, map_sync, }, - { shift = 20, mask = 1, [0] = "strhDL", "ldrhDL", }, - { shift = 20, mask = 1, [0] = "ldrdDL", "ldrsbDL", }, - { shift = 20, mask = 1, [0] = "strdDL", "ldrshDL", }, - }, - _ = { - shift = 20, mask = 25, - [16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, }, - _ = { - shift = 0, mask = 0xffffffff, - [bor(0xe1a00000)] = "nop", - _ = map_data, - } - }, -} - -local map_datai = { - shift = 20, mask = 31, -- NYI: decode PSR bits of msr. Decode imm12. - [16] = "movwDW", [20] = "movtDW", - [18] = { shift = 0, mask = 0xf00ff, [0] = "nopv6", _ = "msrNW", }, - [22] = "msrNW", - _ = map_data, -} - -local map_branch = { - shift = 24, mask = 1, - [0] = "bB", "blB" -} - -local map_condins = { - [0] = map_datar, map_datai, map_load, map_load1, - map_loadm, map_branch, map_loadc, map_datac -} - --- NYI: setend. -local map_uncondins = { - [0] = false, map_simddata, map_simdload, map_preload, - false, "blxB", map_loadcu, map_datacu, -} - ------------------------------------------------------------------------------- - -local map_gpr = { - [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", -} - -local map_cond = { - [0] = "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc", - "hi", "ls", "ge", "lt", "gt", "le", "al", -} - -local map_shift = { [0] = "lsl", "lsr", "asr", "ror", } - ------------------------------------------------------------------------------- - --- Output a nicely formatted line with an opcode and operands. -local function putop(ctx, text, operands) - local pos = ctx.pos - local extra = "" - if ctx.rel then - local sym = ctx.symtab[ctx.rel] - if sym then - extra = "\t->"..sym - elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then - extra = "\t; 0x"..tohex(ctx.rel) - end - end - if ctx.hexdump > 0 then - ctx.out(format("%08x %s %-5s %s%s\n", - ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) - else - ctx.out(format("%08x %-5s %s%s\n", - ctx.addr+pos, text, concat(operands, ", "), extra)) - end - ctx.pos = pos + 4 -end - --- Fallback for unknown opcodes. -local function unknown(ctx) - return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) -end - --- Format operand 2 of load/store opcodes. -local function fmtload(ctx, op, pos) - local base = map_gpr[band(rshift(op, 16), 15)] - local x, ofs - local ext = (band(op, 0x04000000) == 0) - if not ext and band(op, 0x02000000) == 0 then - ofs = band(op, 4095) - if band(op, 0x00800000) == 0 then ofs = -ofs end - if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end - ofs = "#"..ofs - elseif ext and band(op, 0x00400000) ~= 0 then - ofs = band(op, 15) + band(rshift(op, 4), 0xf0) - if band(op, 0x00800000) == 0 then ofs = -ofs end - if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end - ofs = "#"..ofs - else - ofs = map_gpr[band(op, 15)] - if ext or band(op, 0xfe0) == 0 then - elseif band(op, 0xfe0) == 0x60 then - ofs = format("%s, rrx", ofs) - else - local sh = band(rshift(op, 7), 31) - if sh == 0 then sh = 32 end - ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh) - end - if band(op, 0x00800000) == 0 then ofs = "-"..ofs end - end - if ofs == "#0" then - x = format("[%s]", base) - elseif band(op, 0x01000000) == 0 then - x = format("[%s], %s", base, ofs) - else - x = format("[%s, %s]", base, ofs) - end - if band(op, 0x01200000) == 0x01200000 then x = x.."!" end - return x -end - --- Format operand 2 of vector load/store opcodes. -local function fmtvload(ctx, op, pos) - local base = map_gpr[band(rshift(op, 16), 15)] - local ofs = band(op, 255)*4 - if band(op, 0x00800000) == 0 then ofs = -ofs end - if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end - if ofs == 0 then - return format("[%s]", base) - else - return format("[%s, #%d]", base, ofs) - end -end - -local function fmtvr(op, vr, sh0, sh1) - if vr == "s" then - return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1)) - else - return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16)) - end -end - --- Disassemble a single instruction. -local function disass_ins(ctx) - local pos = ctx.pos - local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) - local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) - local operands = {} - local suffix = "" - local last, name, pat - local vr - ctx.op = op - ctx.rel = nil - - local cond = rshift(op, 28) - local opat - if cond == 15 then - opat = map_uncondins[band(rshift(op, 25), 7)] - else - if cond ~= 14 then suffix = map_cond[cond] end - opat = map_condins[band(rshift(op, 25), 7)] - end - while type(opat) ~= "string" do - if not opat then return unknown(ctx) end - opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ - end - name, pat = match(opat, "^([a-z0-9]*)(.*)") - if sub(pat, 1, 1) == "." then - local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") - suffix = suffix..s2 - pat = p2 - end - - for p in gmatch(pat, ".") do - local x = nil - if p == "D" then - x = map_gpr[band(rshift(op, 12), 15)] - elseif p == "N" then - x = map_gpr[band(rshift(op, 16), 15)] - elseif p == "S" then - x = map_gpr[band(rshift(op, 8), 15)] - elseif p == "M" then - x = map_gpr[band(op, 15)] - elseif p == "d" then - x = fmtvr(op, vr, 12, 22) - elseif p == "n" then - x = fmtvr(op, vr, 16, 7) - elseif p == "m" then - x = fmtvr(op, vr, 0, 5) - elseif p == "P" then - if band(op, 0x02000000) ~= 0 then - x = ror(band(op, 255), 2*band(rshift(op, 8), 15)) - else - x = map_gpr[band(op, 15)] - if band(op, 0xff0) ~= 0 then - operands[#operands+1] = x - local s = map_shift[band(rshift(op, 5), 3)] - local r = nil - if band(op, 0xf90) == 0 then - if s == "ror" then s = "rrx" else r = "#32" end - elseif band(op, 0x10) == 0 then - r = "#"..band(rshift(op, 7), 31) - else - r = map_gpr[band(rshift(op, 8), 15)] - end - if name == "mov" then name = s; x = r - elseif r then x = format("%s %s", s, r) - else x = s end - end - end - elseif p == "L" then - x = fmtload(ctx, op, pos) - elseif p == "l" then - x = fmtvload(ctx, op, pos) - elseif p == "B" then - local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6) - if cond == 15 then addr = addr + band(rshift(op, 23), 2) end - ctx.rel = addr - x = "0x"..tohex(addr) - elseif p == "F" then - vr = "s" - elseif p == "G" then - vr = "d" - elseif p == "." then - suffix = suffix..(vr == "s" and ".f32" or ".f64") - elseif p == "R" then - if band(op, 0x00200000) ~= 0 and #operands == 1 then - operands[1] = operands[1].."!" - end - local t = {} - for i=0,15 do - if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end - end - x = "{"..concat(t, ", ").."}" - elseif p == "r" then - if band(op, 0x00200000) ~= 0 and #operands == 2 then - operands[1] = operands[1].."!" - end - local s = tonumber(sub(last, 2)) - local n = band(op, 255) - if vr == "d" then n = rshift(n, 1) end - operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1) - elseif p == "W" then - x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000) - elseif p == "T" then - x = "#0x"..tohex(band(op, 0x00ffffff), 6) - elseif p == "U" then - x = band(rshift(op, 7), 31) - if x == 0 then x = nil end - elseif p == "u" then - x = band(rshift(op, 7), 31) - if band(op, 0x40) == 0 then - if x == 0 then x = nil else x = "lsl #"..x end - else - if x == 0 then x = "asr #32" else x = "asr #"..x end - end - elseif p == "v" then - x = band(rshift(op, 7), 31) - elseif p == "w" then - x = band(rshift(op, 16), 31) - elseif p == "x" then - x = band(rshift(op, 16), 31) + 1 - elseif p == "X" then - x = band(rshift(op, 16), 31) - last + 1 - elseif p == "Y" then - x = band(rshift(op, 12), 0xf0) + band(op, 0x0f) - elseif p == "K" then - x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4) - elseif p == "s" then - if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end - else - assert(false) - end - if x then - last = x - if type(x) == "number" then x = "#"..x end - operands[#operands+1] = x - end - end - - return putop(ctx, name..suffix, operands) -end - ------------------------------------------------------------------------------- - --- Disassemble a block of code. -local function disass_block(ctx, ofs, len) - if not ofs then ofs = 0 end - local stop = len and ofs+len or #ctx.code - ctx.pos = ofs - ctx.rel = nil - while ctx.pos < stop do disass_ins(ctx) end -end - --- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). -local function create(code, addr, out) - local ctx = {} - ctx.code = code - ctx.addr = addr or 0 - ctx.out = out or io.write - ctx.symtab = {} - ctx.disass = disass_block - ctx.hexdump = 8 - return ctx -end - --- Simple API: disassemble code (a string) at address and output via out. -local function disass(code, addr, out) - create(code, addr, out):disass() -end - --- Return register name for RID. -local function regname(r) - if r < 16 then return map_gpr[r] end - return "d"..(r-16) -end - --- Public module functions. -return { - create = create, - disass = disass, - regname = regname -} - diff --git a/Assets/LuaFramework/Luajit/jit/dis_mips.lua b/Assets/LuaFramework/Luajit/jit/dis_mips.lua deleted file mode 100644 index 2bf8b38..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_mips.lua +++ /dev/null @@ -1,428 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT MIPS disassembler module. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT/X license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- This is a helper module used by the LuaJIT machine code dumper module. --- --- It disassembles all standard MIPS32R1/R2 instructions. --- Default mode is big-endian, but see: dis_mipsel.lua ------------------------------------------------------------------------------- - -local type = type -local sub, byte, format = string.sub, string.byte, string.format -local match, gmatch, gsub = string.match, string.gmatch, string.gsub -local concat = table.concat -local bit = require("bit") -local band, bor, tohex = bit.band, bit.bor, bit.tohex -local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift - ------------------------------------------------------------------------------- --- Primary and extended opcode maps ------------------------------------------------------------------------------- - -local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", } -local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", } -local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", } - -local map_special = { - shift = 0, mask = 63, - [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" }, - map_movci, map_srl, "sraDTA", - "sllvDTS", false, map_srlv, "sravDTS", - "jrS", "jalrD1S", "movzDST", "movnDST", - "syscallY", "breakY", false, "sync", - "mfhiD", "mthiS", "mfloD", "mtloS", - false, false, false, false, - "multST", "multuST", "divST", "divuST", - false, false, false, false, - "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T", - "andDST", "orDST", "xorDST", "nor|notDST0", - false, false, "sltDST", "sltuDST", - false, false, false, false, - "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ", - "teqSTZ", false, "tneSTZ", -} - -local map_special2 = { - shift = 0, mask = 63, - [0] = "maddST", "madduST", "mulDST", false, - "msubST", "msubuST", - [32] = "clzDS", [33] = "cloDS", - [63] = "sdbbpY", -} - -local map_bshfl = { - shift = 6, mask = 31, - [2] = "wsbhDT", - [16] = "sebDT", - [24] = "sehDT", -} - -local map_special3 = { - shift = 0, mask = 63, - [0] = "extTSAK", [4] = "insTSAL", - [32] = map_bshfl, - [59] = "rdhwrTD", -} - -local map_regimm = { - shift = 16, mask = 31, - [0] = "bltzSB", "bgezSB", "bltzlSB", "bgezlSB", - false, false, false, false, - "tgeiSI", "tgeiuSI", "tltiSI", "tltiuSI", - "teqiSI", false, "tneiSI", false, - "bltzalSB", "bgezalSB", "bltzallSB", "bgezallSB", - false, false, false, false, - false, false, false, false, - false, false, false, "synciSO", -} - -local map_cop0 = { - shift = 25, mask = 1, - [0] = { - shift = 21, mask = 15, - [0] = "mfc0TDW", [4] = "mtc0TDW", - [10] = "rdpgprDT", - [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", }, - [14] = "wrpgprDT", - }, { - shift = 0, mask = 63, - [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp", - [24] = "eret", [31] = "deret", - [32] = "wait", - }, -} - -local map_cop1s = { - shift = 0, mask = 63, - [0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH", - "sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG", - "round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG", - "round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG", - false, - { shift = 16, mask = 1, [0] = "movf.sFGC", "movt.sFGC" }, - "movz.sFGT", "movn.sFGT", - false, "recip.sFG", "rsqrt.sFG", false, - false, false, false, false, - false, false, false, false, - false, "cvt.d.sFG", false, false, - "cvt.w.sFG", "cvt.l.sFG", "cvt.ps.sFGH", false, - false, false, false, false, - false, false, false, false, - "c.f.sVGH", "c.un.sVGH", "c.eq.sVGH", "c.ueq.sVGH", - "c.olt.sVGH", "c.ult.sVGH", "c.ole.sVGH", "c.ule.sVGH", - "c.sf.sVGH", "c.ngle.sVGH", "c.seq.sVGH", "c.ngl.sVGH", - "c.lt.sVGH", "c.nge.sVGH", "c.le.sVGH", "c.ngt.sVGH", -} - -local map_cop1d = { - shift = 0, mask = 63, - [0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH", - "sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG", - "round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG", - "round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG", - false, - { shift = 16, mask = 1, [0] = "movf.dFGC", "movt.dFGC" }, - "movz.dFGT", "movn.dFGT", - false, "recip.dFG", "rsqrt.dFG", false, - false, false, false, false, - false, false, false, false, - "cvt.s.dFG", false, false, false, - "cvt.w.dFG", "cvt.l.dFG", false, false, - false, false, false, false, - false, false, false, false, - "c.f.dVGH", "c.un.dVGH", "c.eq.dVGH", "c.ueq.dVGH", - "c.olt.dVGH", "c.ult.dVGH", "c.ole.dVGH", "c.ule.dVGH", - "c.df.dVGH", "c.ngle.dVGH", "c.deq.dVGH", "c.ngl.dVGH", - "c.lt.dVGH", "c.nge.dVGH", "c.le.dVGH", "c.ngt.dVGH", -} - -local map_cop1ps = { - shift = 0, mask = 63, - [0] = "add.psFGH", "sub.psFGH", "mul.psFGH", false, - false, "abs.psFG", "mov.psFG", "neg.psFG", - false, false, false, false, - false, false, false, false, - false, - { shift = 16, mask = 1, [0] = "movf.psFGC", "movt.psFGC" }, - "movz.psFGT", "movn.psFGT", - false, false, false, false, - false, false, false, false, - false, false, false, false, - "cvt.s.puFG", false, false, false, - false, false, false, false, - "cvt.s.plFG", false, false, false, - "pll.psFGH", "plu.psFGH", "pul.psFGH", "puu.psFGH", - "c.f.psVGH", "c.un.psVGH", "c.eq.psVGH", "c.ueq.psVGH", - "c.olt.psVGH", "c.ult.psVGH", "c.ole.psVGH", "c.ule.psVGH", - "c.psf.psVGH", "c.ngle.psVGH", "c.pseq.psVGH", "c.ngl.psVGH", - "c.lt.psVGH", "c.nge.psVGH", "c.le.psVGH", "c.ngt.psVGH", -} - -local map_cop1w = { - shift = 0, mask = 63, - [32] = "cvt.s.wFG", [33] = "cvt.d.wFG", -} - -local map_cop1l = { - shift = 0, mask = 63, - [32] = "cvt.s.lFG", [33] = "cvt.d.lFG", -} - -local map_cop1bc = { - shift = 16, mask = 3, - [0] = "bc1fCB", "bc1tCB", "bc1flCB", "bc1tlCB", -} - -local map_cop1 = { - shift = 21, mask = 31, - [0] = "mfc1TG", false, "cfc1TG", "mfhc1TG", - "mtc1TG", false, "ctc1TG", "mthc1TG", - map_cop1bc, false, false, false, - false, false, false, false, - map_cop1s, map_cop1d, false, false, - map_cop1w, map_cop1l, map_cop1ps, -} - -local map_cop1x = { - shift = 0, mask = 63, - [0] = "lwxc1FSX", "ldxc1FSX", false, false, - false, "luxc1FSX", false, false, - "swxc1FSX", "sdxc1FSX", false, false, - false, "suxc1FSX", false, "prefxMSX", - false, false, false, false, - false, false, false, false, - false, false, false, false, - false, false, "alnv.psFGHS", false, - "madd.sFRGH", "madd.dFRGH", false, false, - false, false, "madd.psFRGH", false, - "msub.sFRGH", "msub.dFRGH", false, false, - false, false, "msub.psFRGH", false, - "nmadd.sFRGH", "nmadd.dFRGH", false, false, - false, false, "nmadd.psFRGH", false, - "nmsub.sFRGH", "nmsub.dFRGH", false, false, - false, false, "nmsub.psFRGH", false, -} - -local map_pri = { - [0] = map_special, map_regimm, "jJ", "jalJ", - "beq|beqz|bST00B", "bne|bnezST0B", "blezSB", "bgtzSB", - "addiTSI", "addiu|liTS0I", "sltiTSI", "sltiuTSI", - "andiTSU", "ori|liTS0U", "xoriTSU", "luiTU", - map_cop0, map_cop1, false, map_cop1x, - "beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB", - false, false, false, false, - map_special2, false, false, map_special3, - "lbTSO", "lhTSO", "lwlTSO", "lwTSO", - "lbuTSO", "lhuTSO", "lwrTSO", false, - "sbTSO", "shTSO", "swlTSO", "swTSO", - false, false, "swrTSO", "cacheNSO", - "llTSO", "lwc1HSO", "lwc2TSO", "prefNSO", - false, "ldc1HSO", "ldc2TSO", false, - "scTSO", "swc1HSO", "swc2TSO", false, - false, "sdc1HSO", "sdc2TSO", false, -} - ------------------------------------------------------------------------------- - -local map_gpr = { - [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "sp", "r30", "ra", -} - ------------------------------------------------------------------------------- - --- Output a nicely formatted line with an opcode and operands. -local function putop(ctx, text, operands) - local pos = ctx.pos - local extra = "" - if ctx.rel then - local sym = ctx.symtab[ctx.rel] - if sym then extra = "\t->"..sym end - end - if ctx.hexdump > 0 then - ctx.out(format("%08x %s %-7s %s%s\n", - ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) - else - ctx.out(format("%08x %-7s %s%s\n", - ctx.addr+pos, text, concat(operands, ", "), extra)) - end - ctx.pos = pos + 4 -end - --- Fallback for unknown opcodes. -local function unknown(ctx) - return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) -end - -local function get_be(ctx) - local pos = ctx.pos - local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) - return bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) -end - -local function get_le(ctx) - local pos = ctx.pos - local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) - return bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) -end - --- Disassemble a single instruction. -local function disass_ins(ctx) - local op = ctx:get() - local operands = {} - local last = nil - ctx.op = op - ctx.rel = nil - - local opat = map_pri[rshift(op, 26)] - while type(opat) ~= "string" do - if not opat then return unknown(ctx) end - opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ - end - local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") - local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") - if altname then pat = pat2 end - - for p in gmatch(pat, ".") do - local x = nil - if p == "S" then - x = map_gpr[band(rshift(op, 21), 31)] - elseif p == "T" then - x = map_gpr[band(rshift(op, 16), 31)] - elseif p == "D" then - x = map_gpr[band(rshift(op, 11), 31)] - elseif p == "F" then - x = "f"..band(rshift(op, 6), 31) - elseif p == "G" then - x = "f"..band(rshift(op, 11), 31) - elseif p == "H" then - x = "f"..band(rshift(op, 16), 31) - elseif p == "R" then - x = "f"..band(rshift(op, 21), 31) - elseif p == "A" then - x = band(rshift(op, 6), 31) - elseif p == "M" then - x = band(rshift(op, 11), 31) - elseif p == "N" then - x = band(rshift(op, 16), 31) - elseif p == "C" then - x = band(rshift(op, 18), 7) - if x == 0 then x = nil end - elseif p == "K" then - x = band(rshift(op, 11), 31) + 1 - elseif p == "L" then - x = band(rshift(op, 11), 31) - last + 1 - elseif p == "I" then - x = arshift(lshift(op, 16), 16) - elseif p == "U" then - x = band(op, 0xffff) - elseif p == "O" then - local disp = arshift(lshift(op, 16), 16) - operands[#operands] = format("%d(%s)", disp, last) - elseif p == "X" then - local index = map_gpr[band(rshift(op, 16), 31)] - operands[#operands] = format("%s(%s)", index, last) - elseif p == "B" then - x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4 - ctx.rel = x - x = "0x"..tohex(x) - elseif p == "J" then - x = band(ctx.addr + ctx.pos, 0xf0000000) + band(op, 0x03ffffff)*4 - ctx.rel = x - x = "0x"..tohex(x) - elseif p == "V" then - x = band(rshift(op, 8), 7) - if x == 0 then x = nil end - elseif p == "W" then - x = band(op, 7) - if x == 0 then x = nil end - elseif p == "Y" then - x = band(rshift(op, 6), 0x000fffff) - if x == 0 then x = nil end - elseif p == "Z" then - x = band(rshift(op, 6), 1023) - if x == 0 then x = nil end - elseif p == "0" then - if last == "r0" or last == 0 then - local n = #operands - operands[n] = nil - last = operands[n-1] - if altname then - local a1, a2 = match(altname, "([^|]*)|(.*)") - if a1 then name, altname = a1, a2 - else name = altname end - end - end - elseif p == "1" then - if last == "ra" then - operands[#operands] = nil - end - else - assert(false) - end - if x then operands[#operands+1] = x; last = x end - end - - return putop(ctx, name, operands) -end - ------------------------------------------------------------------------------- - --- Disassemble a block of code. -local function disass_block(ctx, ofs, len) - if not ofs then ofs = 0 end - local stop = len and ofs+len or #ctx.code - stop = stop - stop % 4 - ctx.pos = ofs - ofs % 4 - ctx.rel = nil - while ctx.pos < stop do disass_ins(ctx) end -end - --- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). -local function create(code, addr, out) - local ctx = {} - ctx.code = code - ctx.addr = addr or 0 - ctx.out = out or io.write - ctx.symtab = {} - ctx.disass = disass_block - ctx.hexdump = 8 - ctx.get = get_be - return ctx -end - -local function create_el(code, addr, out) - local ctx = create(code, addr, out) - ctx.get = get_le - return ctx -end - --- Simple API: disassemble code (a string) at address and output via out. -local function disass(code, addr, out) - create(code, addr, out):disass() -end - -local function disass_el(code, addr, out) - create_el(code, addr, out):disass() -end - --- Return register name for RID. -local function regname(r) - if r < 32 then return map_gpr[r] end - return "f"..(r-32) -end - --- Public module functions. -return { - create = create, - create_el = create_el, - disass = disass, - disass_el = disass_el, - regname = regname -} - diff --git a/Assets/LuaFramework/Luajit/jit/dis_mipsel.lua b/Assets/LuaFramework/Luajit/jit/dis_mipsel.lua deleted file mode 100644 index 3f2f6ef..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_mipsel.lua +++ /dev/null @@ -1,17 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT MIPSEL disassembler wrapper module. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- This module just exports the little-endian functions from the --- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------- - -local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") -return { - create = dis_mips.create_el, - disass = dis_mips.disass_el, - regname = dis_mips.regname -} - diff --git a/Assets/LuaFramework/Luajit/jit/dis_mipsel.lua.meta b/Assets/LuaFramework/Luajit/jit/dis_mipsel.lua.meta deleted file mode 100644 index 481244e..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_mipsel.lua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 06a369592f16cc54b82ec90d905c271c -DefaultImporter: - userData: diff --git a/Assets/LuaFramework/Luajit/jit/dis_ppc.lua b/Assets/LuaFramework/Luajit/jit/dis_ppc.lua deleted file mode 100644 index 30f51ec..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_ppc.lua +++ /dev/null @@ -1,591 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT PPC disassembler module. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT/X license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- This is a helper module used by the LuaJIT machine code dumper module. --- --- It disassembles all common, non-privileged 32/64 bit PowerPC instructions --- plus the e500 SPE instructions and some Cell/Xenon extensions. --- --- NYI: VMX, VMX128 ------------------------------------------------------------------------------- - -local type = type -local sub, byte, format = string.sub, string.byte, string.format -local match, gmatch, gsub = string.match, string.gmatch, string.gsub -local concat = table.concat -local bit = require("bit") -local band, bor, tohex = bit.band, bit.bor, bit.tohex -local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift - ------------------------------------------------------------------------------- --- Primary and extended opcode maps ------------------------------------------------------------------------------- - -local map_crops = { - shift = 1, mask = 1023, - [0] = "mcrfXX", - [33] = "crnor|crnotCCC=", [129] = "crandcCCC", - [193] = "crxor|crclrCCC%", [225] = "crnandCCC", - [257] = "crandCCC", [289] = "creqv|crsetCCC%", - [417] = "crorcCCC", [449] = "cror|crmoveCCC=", - [16] = "b_lrKB", [528] = "b_ctrKB", - [150] = "isync", -} - -local map_rlwinm = setmetatable({ - shift = 0, mask = -1, -}, -{ __index = function(t, x) - local rot = band(rshift(x, 11), 31) - local mb = band(rshift(x, 6), 31) - local me = band(rshift(x, 1), 31) - if mb == 0 and me == 31-rot then - return "slwiRR~A." - elseif me == 31 and mb == 32-rot then - return "srwiRR~-A." - else - return "rlwinmRR~AAA." - end - end -}) - -local map_rld = { - shift = 2, mask = 7, - [0] = "rldiclRR~HM.", "rldicrRR~HM.", "rldicRR~HM.", "rldimiRR~HM.", - { - shift = 1, mask = 1, - [0] = "rldclRR~RM.", "rldcrRR~RM.", - }, -} - -local map_ext = setmetatable({ - shift = 1, mask = 1023, - - [0] = "cmp_YLRR", [32] = "cmpl_YLRR", - [4] = "twARR", [68] = "tdARR", - - [8] = "subfcRRR.", [40] = "subfRRR.", - [104] = "negRR.", [136] = "subfeRRR.", - [200] = "subfzeRR.", [232] = "subfmeRR.", - [520] = "subfcoRRR.", [552] = "subfoRRR.", - [616] = "negoRR.", [648] = "subfeoRRR.", - [712] = "subfzeoRR.", [744] = "subfmeoRR.", - - [9] = "mulhduRRR.", [73] = "mulhdRRR.", [233] = "mulldRRR.", - [457] = "divduRRR.", [489] = "divdRRR.", - [745] = "mulldoRRR.", - [969] = "divduoRRR.", [1001] = "divdoRRR.", - - [10] = "addcRRR.", [138] = "addeRRR.", - [202] = "addzeRR.", [234] = "addmeRR.", [266] = "addRRR.", - [522] = "addcoRRR.", [650] = "addeoRRR.", - [714] = "addzeoRR.", [746] = "addmeoRR.", [778] = "addoRRR.", - - [11] = "mulhwuRRR.", [75] = "mulhwRRR.", [235] = "mullwRRR.", - [459] = "divwuRRR.", [491] = "divwRRR.", - [747] = "mullwoRRR.", - [971] = "divwouRRR.", [1003] = "divwoRRR.", - - [15] = "iselltRRR", [47] = "iselgtRRR", [79] = "iseleqRRR", - - [144] = { shift = 20, mask = 1, [0] = "mtcrfRZ~", "mtocrfRZ~", }, - [19] = { shift = 20, mask = 1, [0] = "mfcrR", "mfocrfRZ", }, - [371] = { shift = 11, mask = 1023, [392] = "mftbR", [424] = "mftbuR", }, - [339] = { - shift = 11, mask = 1023, - [32] = "mferR", [256] = "mflrR", [288] = "mfctrR", [16] = "mfspefscrR", - }, - [467] = { - shift = 11, mask = 1023, - [32] = "mtxerR", [256] = "mtlrR", [288] = "mtctrR", [16] = "mtspefscrR", - }, - - [20] = "lwarxRR0R", [84] = "ldarxRR0R", - - [21] = "ldxRR0R", [53] = "lduxRRR", - [149] = "stdxRR0R", [181] = "stduxRRR", - [341] = "lwaxRR0R", [373] = "lwauxRRR", - - [23] = "lwzxRR0R", [55] = "lwzuxRRR", - [87] = "lbzxRR0R", [119] = "lbzuxRRR", - [151] = "stwxRR0R", [183] = "stwuxRRR", - [215] = "stbxRR0R", [247] = "stbuxRRR", - [279] = "lhzxRR0R", [311] = "lhzuxRRR", - [343] = "lhaxRR0R", [375] = "lhauxRRR", - [407] = "sthxRR0R", [439] = "sthuxRRR", - - [54] = "dcbst-R0R", [86] = "dcbf-R0R", - [150] = "stwcxRR0R.", [214] = "stdcxRR0R.", - [246] = "dcbtst-R0R", [278] = "dcbt-R0R", - [310] = "eciwxRR0R", [438] = "ecowxRR0R", - [470] = "dcbi-RR", - - [598] = { - shift = 21, mask = 3, - [0] = "sync", "lwsync", "ptesync", - }, - [758] = "dcba-RR", - [854] = "eieio", [982] = "icbi-R0R", [1014] = "dcbz-R0R", - - [26] = "cntlzwRR~", [58] = "cntlzdRR~", - [122] = "popcntbRR~", - [154] = "prtywRR~", [186] = "prtydRR~", - - [28] = "andRR~R.", [60] = "andcRR~R.", [124] = "nor|notRR~R=.", - [284] = "eqvRR~R.", [316] = "xorRR~R.", - [412] = "orcRR~R.", [444] = "or|mrRR~R=.", [476] = "nandRR~R.", - [508] = "cmpbRR~R", - - [512] = "mcrxrX", - - [532] = "ldbrxRR0R", [660] = "stdbrxRR0R", - - [533] = "lswxRR0R", [597] = "lswiRR0A", - [661] = "stswxRR0R", [725] = "stswiRR0A", - - [534] = "lwbrxRR0R", [662] = "stwbrxRR0R", - [790] = "lhbrxRR0R", [918] = "sthbrxRR0R", - - [535] = "lfsxFR0R", [567] = "lfsuxFRR", - [599] = "lfdxFR0R", [631] = "lfduxFRR", - [663] = "stfsxFR0R", [695] = "stfsuxFRR", - [727] = "stfdxFR0R", [759] = "stfduxFR0R", - [855] = "lfiwaxFR0R", - [983] = "stfiwxFR0R", - - [24] = "slwRR~R.", - - [27] = "sldRR~R.", [536] = "srwRR~R.", - [792] = "srawRR~R.", [824] = "srawiRR~A.", - - [794] = "sradRR~R.", [826] = "sradiRR~H.", [827] = "sradiRR~H.", - [922] = "extshRR~.", [954] = "extsbRR~.", [986] = "extswRR~.", - - [539] = "srdRR~R.", -}, -{ __index = function(t, x) - if band(x, 31) == 15 then return "iselRRRC" end - end -}) - -local map_ld = { - shift = 0, mask = 3, - [0] = "ldRRE", "lduRRE", "lwaRRE", -} - -local map_std = { - shift = 0, mask = 3, - [0] = "stdRRE", "stduRRE", -} - -local map_fps = { - shift = 5, mask = 1, - { - shift = 1, mask = 15, - [0] = false, false, "fdivsFFF.", false, - "fsubsFFF.", "faddsFFF.", "fsqrtsF-F.", false, - "fresF-F.", "fmulsFF-F.", "frsqrtesF-F.", false, - "fmsubsFFFF~.", "fmaddsFFFF~.", "fnmsubsFFFF~.", "fnmaddsFFFF~.", - } -} - -local map_fpd = { - shift = 5, mask = 1, - [0] = { - shift = 1, mask = 1023, - [0] = "fcmpuXFF", [32] = "fcmpoXFF", [64] = "mcrfsXX", - [38] = "mtfsb1A.", [70] = "mtfsb0A.", [134] = "mtfsfiA>>-A>", - [8] = "fcpsgnFFF.", [40] = "fnegF-F.", [72] = "fmrF-F.", - [136] = "fnabsF-F.", [264] = "fabsF-F.", - [12] = "frspF-F.", - [14] = "fctiwF-F.", [15] = "fctiwzF-F.", - [583] = "mffsF.", [711] = "mtfsfZF.", - [392] = "frinF-F.", [424] = "frizF-F.", - [456] = "fripF-F.", [488] = "frimF-F.", - [814] = "fctidF-F.", [815] = "fctidzF-F.", [846] = "fcfidF-F.", - }, - { - shift = 1, mask = 15, - [0] = false, false, "fdivFFF.", false, - "fsubFFF.", "faddFFF.", "fsqrtF-F.", "fselFFFF~.", - "freF-F.", "fmulFF-F.", "frsqrteF-F.", false, - "fmsubFFFF~.", "fmaddFFFF~.", "fnmsubFFFF~.", "fnmaddFFFF~.", - } -} - -local map_spe = { - shift = 0, mask = 2047, - - [512] = "evaddwRRR", [514] = "evaddiwRAR~", - [516] = "evsubwRRR~", [518] = "evsubiwRAR~", - [520] = "evabsRR", [521] = "evnegRR", - [522] = "evextsbRR", [523] = "evextshRR", [524] = "evrndwRR", - [525] = "evcntlzwRR", [526] = "evcntlswRR", - - [527] = "brincRRR", - - [529] = "evandRRR", [530] = "evandcRRR", [534] = "evxorRRR", - [535] = "evor|evmrRRR=", [536] = "evnor|evnotRRR=", - [537] = "eveqvRRR", [539] = "evorcRRR", [542] = "evnandRRR", - - [544] = "evsrwuRRR", [545] = "evsrwsRRR", - [546] = "evsrwiuRRA", [547] = "evsrwisRRA", - [548] = "evslwRRR", [550] = "evslwiRRA", - [552] = "evrlwRRR", [553] = "evsplatiRS", - [554] = "evrlwiRRA", [555] = "evsplatfiRS", - [556] = "evmergehiRRR", [557] = "evmergeloRRR", - [558] = "evmergehiloRRR", [559] = "evmergelohiRRR", - - [560] = "evcmpgtuYRR", [561] = "evcmpgtsYRR", - [562] = "evcmpltuYRR", [563] = "evcmpltsYRR", - [564] = "evcmpeqYRR", - - [632] = "evselRRR", [633] = "evselRRRW", - [634] = "evselRRRW", [635] = "evselRRRW", - [636] = "evselRRRW", [637] = "evselRRRW", - [638] = "evselRRRW", [639] = "evselRRRW", - - [640] = "evfsaddRRR", [641] = "evfssubRRR", - [644] = "evfsabsRR", [645] = "evfsnabsRR", [646] = "evfsnegRR", - [648] = "evfsmulRRR", [649] = "evfsdivRRR", - [652] = "evfscmpgtYRR", [653] = "evfscmpltYRR", [654] = "evfscmpeqYRR", - [656] = "evfscfuiR-R", [657] = "evfscfsiR-R", - [658] = "evfscfufR-R", [659] = "evfscfsfR-R", - [660] = "evfsctuiR-R", [661] = "evfsctsiR-R", - [662] = "evfsctufR-R", [663] = "evfsctsfR-R", - [664] = "evfsctuizR-R", [666] = "evfsctsizR-R", - [668] = "evfststgtYRR", [669] = "evfststltYRR", [670] = "evfststeqYRR", - - [704] = "efsaddRRR", [705] = "efssubRRR", - [708] = "efsabsRR", [709] = "efsnabsRR", [710] = "efsnegRR", - [712] = "efsmulRRR", [713] = "efsdivRRR", - [716] = "efscmpgtYRR", [717] = "efscmpltYRR", [718] = "efscmpeqYRR", - [719] = "efscfdR-R", - [720] = "efscfuiR-R", [721] = "efscfsiR-R", - [722] = "efscfufR-R", [723] = "efscfsfR-R", - [724] = "efsctuiR-R", [725] = "efsctsiR-R", - [726] = "efsctufR-R", [727] = "efsctsfR-R", - [728] = "efsctuizR-R", [730] = "efsctsizR-R", - [732] = "efststgtYRR", [733] = "efststltYRR", [734] = "efststeqYRR", - - [736] = "efdaddRRR", [737] = "efdsubRRR", - [738] = "efdcfuidR-R", [739] = "efdcfsidR-R", - [740] = "efdabsRR", [741] = "efdnabsRR", [742] = "efdnegRR", - [744] = "efdmulRRR", [745] = "efddivRRR", - [746] = "efdctuidzR-R", [747] = "efdctsidzR-R", - [748] = "efdcmpgtYRR", [749] = "efdcmpltYRR", [750] = "efdcmpeqYRR", - [751] = "efdcfsR-R", - [752] = "efdcfuiR-R", [753] = "efdcfsiR-R", - [754] = "efdcfufR-R", [755] = "efdcfsfR-R", - [756] = "efdctuiR-R", [757] = "efdctsiR-R", - [758] = "efdctufR-R", [759] = "efdctsfR-R", - [760] = "efdctuizR-R", [762] = "efdctsizR-R", - [764] = "efdtstgtYRR", [765] = "efdtstltYRR", [766] = "efdtsteqYRR", - - [768] = "evlddxRR0R", [769] = "evlddRR8", - [770] = "evldwxRR0R", [771] = "evldwRR8", - [772] = "evldhxRR0R", [773] = "evldhRR8", - [776] = "evlhhesplatxRR0R", [777] = "evlhhesplatRR2", - [780] = "evlhhousplatxRR0R", [781] = "evlhhousplatRR2", - [782] = "evlhhossplatxRR0R", [783] = "evlhhossplatRR2", - [784] = "evlwhexRR0R", [785] = "evlwheRR4", - [788] = "evlwhouxRR0R", [789] = "evlwhouRR4", - [790] = "evlwhosxRR0R", [791] = "evlwhosRR4", - [792] = "evlwwsplatxRR0R", [793] = "evlwwsplatRR4", - [796] = "evlwhsplatxRR0R", [797] = "evlwhsplatRR4", - - [800] = "evstddxRR0R", [801] = "evstddRR8", - [802] = "evstdwxRR0R", [803] = "evstdwRR8", - [804] = "evstdhxRR0R", [805] = "evstdhRR8", - [816] = "evstwhexRR0R", [817] = "evstwheRR4", - [820] = "evstwhoxRR0R", [821] = "evstwhoRR4", - [824] = "evstwwexRR0R", [825] = "evstwweRR4", - [828] = "evstwwoxRR0R", [829] = "evstwwoRR4", - - [1027] = "evmhessfRRR", [1031] = "evmhossfRRR", [1032] = "evmheumiRRR", - [1033] = "evmhesmiRRR", [1035] = "evmhesmfRRR", [1036] = "evmhoumiRRR", - [1037] = "evmhosmiRRR", [1039] = "evmhosmfRRR", [1059] = "evmhessfaRRR", - [1063] = "evmhossfaRRR", [1064] = "evmheumiaRRR", [1065] = "evmhesmiaRRR", - [1067] = "evmhesmfaRRR", [1068] = "evmhoumiaRRR", [1069] = "evmhosmiaRRR", - [1071] = "evmhosmfaRRR", [1095] = "evmwhssfRRR", [1096] = "evmwlumiRRR", - [1100] = "evmwhumiRRR", [1101] = "evmwhsmiRRR", [1103] = "evmwhsmfRRR", - [1107] = "evmwssfRRR", [1112] = "evmwumiRRR", [1113] = "evmwsmiRRR", - [1115] = "evmwsmfRRR", [1127] = "evmwhssfaRRR", [1128] = "evmwlumiaRRR", - [1132] = "evmwhumiaRRR", [1133] = "evmwhsmiaRRR", [1135] = "evmwhsmfaRRR", - [1139] = "evmwssfaRRR", [1144] = "evmwumiaRRR", [1145] = "evmwsmiaRRR", - [1147] = "evmwsmfaRRR", - - [1216] = "evaddusiaawRR", [1217] = "evaddssiaawRR", - [1218] = "evsubfusiaawRR", [1219] = "evsubfssiaawRR", - [1220] = "evmraRR", - [1222] = "evdivwsRRR", [1223] = "evdivwuRRR", - [1224] = "evaddumiaawRR", [1225] = "evaddsmiaawRR", - [1226] = "evsubfumiaawRR", [1227] = "evsubfsmiaawRR", - - [1280] = "evmheusiaawRRR", [1281] = "evmhessiaawRRR", - [1283] = "evmhessfaawRRR", [1284] = "evmhousiaawRRR", - [1285] = "evmhossiaawRRR", [1287] = "evmhossfaawRRR", - [1288] = "evmheumiaawRRR", [1289] = "evmhesmiaawRRR", - [1291] = "evmhesmfaawRRR", [1292] = "evmhoumiaawRRR", - [1293] = "evmhosmiaawRRR", [1295] = "evmhosmfaawRRR", - [1320] = "evmhegumiaaRRR", [1321] = "evmhegsmiaaRRR", - [1323] = "evmhegsmfaaRRR", [1324] = "evmhogumiaaRRR", - [1325] = "evmhogsmiaaRRR", [1327] = "evmhogsmfaaRRR", - [1344] = "evmwlusiaawRRR", [1345] = "evmwlssiaawRRR", - [1352] = "evmwlumiaawRRR", [1353] = "evmwlsmiaawRRR", - [1363] = "evmwssfaaRRR", [1368] = "evmwumiaaRRR", - [1369] = "evmwsmiaaRRR", [1371] = "evmwsmfaaRRR", - [1408] = "evmheusianwRRR", [1409] = "evmhessianwRRR", - [1411] = "evmhessfanwRRR", [1412] = "evmhousianwRRR", - [1413] = "evmhossianwRRR", [1415] = "evmhossfanwRRR", - [1416] = "evmheumianwRRR", [1417] = "evmhesmianwRRR", - [1419] = "evmhesmfanwRRR", [1420] = "evmhoumianwRRR", - [1421] = "evmhosmianwRRR", [1423] = "evmhosmfanwRRR", - [1448] = "evmhegumianRRR", [1449] = "evmhegsmianRRR", - [1451] = "evmhegsmfanRRR", [1452] = "evmhogumianRRR", - [1453] = "evmhogsmianRRR", [1455] = "evmhogsmfanRRR", - [1472] = "evmwlusianwRRR", [1473] = "evmwlssianwRRR", - [1480] = "evmwlumianwRRR", [1481] = "evmwlsmianwRRR", - [1491] = "evmwssfanRRR", [1496] = "evmwumianRRR", - [1497] = "evmwsmianRRR", [1499] = "evmwsmfanRRR", -} - -local map_pri = { - [0] = false, false, "tdiARI", "twiARI", - map_spe, false, false, "mulliRRI", - "subficRRI", false, "cmpl_iYLRU", "cmp_iYLRI", - "addicRRI", "addic.RRI", "addi|liRR0I", "addis|lisRR0I", - "b_KBJ", "sc", "bKJ", map_crops, - "rlwimiRR~AAA.", map_rlwinm, false, "rlwnmRR~RAA.", - "oriNRR~U", "orisRR~U", "xoriRR~U", "xorisRR~U", - "andi.RR~U", "andis.RR~U", map_rld, map_ext, - "lwzRRD", "lwzuRRD", "lbzRRD", "lbzuRRD", - "stwRRD", "stwuRRD", "stbRRD", "stbuRRD", - "lhzRRD", "lhzuRRD", "lhaRRD", "lhauRRD", - "sthRRD", "sthuRRD", "lmwRRD", "stmwRRD", - "lfsFRD", "lfsuFRD", "lfdFRD", "lfduFRD", - "stfsFRD", "stfsuFRD", "stfdFRD", "stfduFRD", - false, false, map_ld, map_fps, - false, false, map_std, map_fpd, -} - ------------------------------------------------------------------------------- - -local map_gpr = { - [0] = "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", -} - -local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", } - --- Format a condition bit. -local function condfmt(cond) - if cond <= 3 then - return map_cond[band(cond, 3)] - else - return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)]) - end -end - ------------------------------------------------------------------------------- - --- Output a nicely formatted line with an opcode and operands. -local function putop(ctx, text, operands) - local pos = ctx.pos - local extra = "" - if ctx.rel then - local sym = ctx.symtab[ctx.rel] - if sym then extra = "\t->"..sym end - end - if ctx.hexdump > 0 then - ctx.out(format("%08x %s %-7s %s%s\n", - ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) - else - ctx.out(format("%08x %-7s %s%s\n", - ctx.addr+pos, text, concat(operands, ", "), extra)) - end - ctx.pos = pos + 4 -end - --- Fallback for unknown opcodes. -local function unknown(ctx) - return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) -end - --- Disassemble a single instruction. -local function disass_ins(ctx) - local pos = ctx.pos - local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) - local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) - local operands = {} - local last = nil - local rs = 21 - ctx.op = op - ctx.rel = nil - - local opat = map_pri[rshift(b0, 2)] - while type(opat) ~= "string" do - if not opat then return unknown(ctx) end - opat = opat[band(rshift(op, opat.shift), opat.mask)] - end - local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") - local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)") - if altname then pat = pat2 end - - for p in gmatch(pat, ".") do - local x = nil - if p == "R" then - x = map_gpr[band(rshift(op, rs), 31)] - rs = rs - 5 - elseif p == "F" then - x = "f"..band(rshift(op, rs), 31) - rs = rs - 5 - elseif p == "A" then - x = band(rshift(op, rs), 31) - rs = rs - 5 - elseif p == "S" then - x = arshift(lshift(op, 27-rs), 27) - rs = rs - 5 - elseif p == "I" then - x = arshift(lshift(op, 16), 16) - elseif p == "U" then - x = band(op, 0xffff) - elseif p == "D" or p == "E" then - local disp = arshift(lshift(op, 16), 16) - if p == "E" then disp = band(disp, -4) end - if last == "r0" then last = "0" end - operands[#operands] = format("%d(%s)", disp, last) - elseif p >= "2" and p <= "8" then - local disp = band(rshift(op, rs), 31) * p - if last == "r0" then last = "0" end - operands[#operands] = format("%d(%s)", disp, last) - elseif p == "H" then - x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4) - rs = rs - 5 - elseif p == "M" then - x = band(rshift(op, rs), 31) + band(op, 0x20) - elseif p == "C" then - x = condfmt(band(rshift(op, rs), 31)) - rs = rs - 5 - elseif p == "B" then - local bo = rshift(op, 21) - local cond = band(rshift(op, 16), 31) - local cn = "" - rs = rs - 10 - if band(bo, 4) == 0 then - cn = band(bo, 2) == 0 and "dnz" or "dz" - if band(bo, 0x10) == 0 then - cn = cn..(band(bo, 8) == 0 and "f" or "t") - end - if band(bo, 0x10) == 0 then x = condfmt(cond) end - name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") - elseif band(bo, 0x10) == 0 then - cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)] - if cond > 3 then x = "cr"..rshift(cond, 2) end - name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") - end - name = gsub(name, "_", cn) - elseif p == "J" then - x = arshift(lshift(op, 27-rs), 29-rs)*4 - if band(op, 2) == 0 then x = ctx.addr + pos + x end - ctx.rel = x - x = "0x"..tohex(x) - elseif p == "K" then - if band(op, 1) ~= 0 then name = name.."l" end - if band(op, 2) ~= 0 then name = name.."a" end - elseif p == "X" or p == "Y" then - x = band(rshift(op, rs+2), 7) - if x == 0 and p == "Y" then x = nil else x = "cr"..x end - rs = rs - 5 - elseif p == "W" then - x = "cr"..band(op, 7) - elseif p == "Z" then - x = band(rshift(op, rs-4), 255) - rs = rs - 10 - elseif p == ">" then - operands[#operands] = rshift(operands[#operands], 1) - elseif p == "0" then - if last == "r0" then - operands[#operands] = nil - if altname then name = altname end - end - elseif p == "L" then - name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w") - elseif p == "." then - if band(op, 1) == 1 then name = name.."." end - elseif p == "N" then - if op == 0x60000000 then name = "nop"; break end - elseif p == "~" then - local n = #operands - operands[n-1], operands[n] = operands[n], operands[n-1] - elseif p == "=" then - local n = #operands - if last == operands[n-1] then - operands[n] = nil - name = altname - end - elseif p == "%" then - local n = #operands - if last == operands[n-1] and last == operands[n-2] then - operands[n] = nil - operands[n-1] = nil - name = altname - end - elseif p == "-" then - rs = rs - 5 - else - assert(false) - end - if x then operands[#operands+1] = x; last = x end - end - - return putop(ctx, name, operands) -end - ------------------------------------------------------------------------------- - --- Disassemble a block of code. -local function disass_block(ctx, ofs, len) - if not ofs then ofs = 0 end - local stop = len and ofs+len or #ctx.code - stop = stop - stop % 4 - ctx.pos = ofs - ofs % 4 - ctx.rel = nil - while ctx.pos < stop do disass_ins(ctx) end -end - --- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). -local function create(code, addr, out) - local ctx = {} - ctx.code = code - ctx.addr = addr or 0 - ctx.out = out or io.write - ctx.symtab = {} - ctx.disass = disass_block - ctx.hexdump = 8 - return ctx -end - --- Simple API: disassemble code (a string) at address and output via out. -local function disass(code, addr, out) - create(code, addr, out):disass() -end - --- Return register name for RID. -local function regname(r) - if r < 32 then return map_gpr[r] end - return "f"..(r-32) -end - --- Public module functions. -return { - create = create, - disass = disass, - regname = regname -} - diff --git a/Assets/LuaFramework/Luajit/jit/dis_ppc.lua.meta b/Assets/LuaFramework/Luajit/jit/dis_ppc.lua.meta deleted file mode 100644 index 46faada..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_ppc.lua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 16a81ab6de25d044280dbc5a24abfa3a -DefaultImporter: - userData: diff --git a/Assets/LuaFramework/Luajit/jit/dis_x64.lua b/Assets/LuaFramework/Luajit/jit/dis_x64.lua deleted file mode 100644 index 077b1b1..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_x64.lua +++ /dev/null @@ -1,17 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT x64 disassembler wrapper module. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- This module just exports the 64 bit functions from the combined --- x86/x64 disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------- - -local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86") -return { - create = dis_x86.create64, - disass = dis_x86.disass64, - regname = dis_x86.regname64 -} - diff --git a/Assets/LuaFramework/Luajit/jit/dis_x64.lua.meta b/Assets/LuaFramework/Luajit/jit/dis_x64.lua.meta deleted file mode 100644 index 0e6dbd8..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_x64.lua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: da9358785297a39428fd96e0e17ad8f7 -DefaultImporter: - userData: diff --git a/Assets/LuaFramework/Luajit/jit/dis_x86.lua b/Assets/LuaFramework/Luajit/jit/dis_x86.lua deleted file mode 100644 index f8a21ff..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_x86.lua +++ /dev/null @@ -1,928 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT x86/x64 disassembler module. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- This is a helper module used by the LuaJIT machine code dumper module. --- --- Sending small code snippets to an external disassembler and mixing the --- output with our own stuff was too fragile. So I had to bite the bullet --- and write yet another x86 disassembler. Oh well ... --- --- The output format is very similar to what ndisasm generates. But it has --- been developed independently by looking at the opcode tables from the --- Intel and AMD manuals. The supported instruction set is quite extensive --- and reflects what a current generation Intel or AMD CPU implements in --- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3, --- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor --- (VMX/SVM) instructions. --- --- Notes: --- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported. --- * No attempt at optimization has been made -- it's fast enough for my needs. ------------------------------------------------------------------------------- - -local type = type -local sub, byte, format = string.sub, string.byte, string.format -local match, gmatch, gsub = string.match, string.gmatch, string.gsub -local lower, rep = string.lower, string.rep -local bit = require("bit") -local tohex = bit.tohex - --- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on. -local map_opc1_32 = { ---0x -[0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es", -"orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*", ---1x -"adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss", -"sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds", ---2x -"andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa", -"subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das", ---3x -"xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa", -"cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas", ---4x -"incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR", -"decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR", ---5x -"pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR", -"popUR","popUR","popUR","popUR","popUR","popUR","popUR","popUR", ---6x -"sz*pushaw,pusha","sz*popaw,popa","boundVrm","arplWmr", -"fs:seg","gs:seg","o16:","a16", -"pushUi","imulVrmi","pushBs","imulVrms", -"insb","insVS","outsb","outsVS", ---7x -"joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj", -"jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj", ---8x -"arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms", -"testBmr","testVmr","xchgBrm","xchgVrm", -"movBmr","movVmr","movBrm","movVrm", -"movVmg","leaVrm","movWgm","popUm", ---9x -"nop*xchgVaR|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR", -"xchgVaR","xchgVaR","xchgVaR","xchgVaR", -"sz*cbw,cwde,cdqe","sz*cwd,cdq,cqo","call farViw","wait", -"sz*pushfw,pushf","sz*popfw,popf","sahf","lahf", ---Ax -"movBao","movVao","movBoa","movVoa", -"movsb","movsVS","cmpsb","cmpsVS", -"testBai","testVai","stosb","stosVS", -"lodsb","lodsVS","scasb","scasVS", ---Bx -"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi", -"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI", ---Cx -"shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi", -"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS", ---Dx -"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb", -"fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7", ---Ex -"loopneBj","loopeBj","loopBj","sz*jcxzBj,jecxzBj,jrcxzBj", -"inBau","inVau","outBua","outVua", -"callVj","jmpVj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda", ---Fx -"lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm", -"clc","stc","cli","sti","cld","std","incb!Bm","incd!Vm", -} -assert(#map_opc1_32 == 255) - --- Map for 1st opcode byte in 64 bit mode (overrides only). -local map_opc1_64 = setmetatable({ - [0x06]=false, [0x07]=false, [0x0e]=false, - [0x16]=false, [0x17]=false, [0x1e]=false, [0x1f]=false, - [0x27]=false, [0x2f]=false, [0x37]=false, [0x3f]=false, - [0x60]=false, [0x61]=false, [0x62]=false, [0x63]="movsxdVrDmt", [0x67]="a32:", - [0x40]="rex*", [0x41]="rex*b", [0x42]="rex*x", [0x43]="rex*xb", - [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb", - [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb", - [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb", - [0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false, - [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false, -}, { __index = map_opc1_32 }) - --- Map for 2nd opcode byte (0F xx). True CISC hell. Hey, I told you. --- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne, -|F3|66|F2 -local map_opc2 = { ---0x -[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret", -"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu", ---1x -"movupsXrm|movssXrvm|movupdXrm|movsdXrvm", -"movupsXmr|movssXmvr|movupdXmr|movsdXmvr", -"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", -"movlpsXmr||movlpdXmr", -"unpcklpsXrvm||unpcklpdXrvm", -"unpckhpsXrvm||unpckhpdXrvm", -"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm", -"movhpsXmr||movhpdXmr", -"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm", -"hintnopVm","hintnopVm","hintnopVm","hintnopVm", ---2x -"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil, -"movapsXrm||movapdXrm", -"movapsXmr||movapdXmr", -"cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt", -"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr", -"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm", -"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm", -"ucomissXrm||ucomisdXrm", -"comissXrm||comisdXrm", ---3x -"wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,"getsec", -"opc3*38",nil,"opc3*3a",nil,nil,nil,nil,nil, ---4x -"cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm", -"cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm", -"cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm", -"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm", ---5x -"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm", -"rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm", -"andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm", -"orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm", -"addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm", -"cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm", -"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm", -"subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm", -"divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm", ---6x -"punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm", -"pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm", -"punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm", -"||punpcklqdqXrvm","||punpckhqdqXrvm", -"movPrVSm","movqMrm|movdquXrm|movdqaXrm", ---7x -"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pvmu", -"pshiftd!Pvmu","pshiftq!Mvmu||pshiftdq!Xvmu", -"pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|", -"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$", -nil,nil, -"||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm", -"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr", ---8x -"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj", -"jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj", ---9x -"setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm", -"setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm", ---Ax -"push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil, -"push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm", ---Bx -"cmpxchgBmr","cmpxchgVmr","$lssVrm","btrVmr", -"$lfsVrm","$lgsVrm","movzxVrBmt","movzxVrWmt", -"|popcntVrm","ud2Dp","bt!Vmu","btcVmr", -"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt", ---Cx -"xaddBmr","xaddVmr", -"cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|", -"pinsrwPrvWmu","pextrwDrPmu", -"shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp", -"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR", ---Dx -"||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm", -"paddqPrvm","pmullwPrvm", -"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm", -"psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm", -"paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm", ---Ex -"pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm", -"pmulhuwPrvm","pmulhwPrvm", -"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr", -"psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm", -"paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm", ---Fx -"|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm", -"pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$", -"psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm", -"paddbPrvm","paddwPrvm","padddPrvm","ud", -} -assert(map_opc2[255] == "ud") - --- Map for three-byte opcodes. Can't wait for their next invention. -local map_opc3 = { -["38"] = { -- [66] 0f 38 xx ---0x -[0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm", -"pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm", -"psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm", -"||permilpsXrvm","||permilpdXrvm",nil,nil, ---1x -"||pblendvbXrma",nil,nil,nil, -"||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm", -"||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil, -"pabsbPrm","pabswPrm","pabsdPrm",nil, ---2x -"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm", -"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil, -"||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm", -"||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr", ---3x -"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm", -"||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm", -"||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm", -"||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm", ---4x -"||pmulddXrvm","||phminposuwXrm",nil,nil, -nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm", ---5x -[0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm", -[0x5a] = "||broadcasti128XrlXm", ---7x -[0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm", ---8x -[0x8c] = "||pmaskmovXrvVSm", -[0x8e] = "||pmaskmovVSmXvr", ---Dx -[0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm", -[0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm", ---Fx -[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt", -}, - -["3a"] = { -- [66] 0f 3a xx ---0x -[0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil, -"||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil, -"||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu", -"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu", ---1x -nil,nil,nil,nil, -"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru", -"||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil, -nil,nil,nil,nil, ---2x -"||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil, ---3x -[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru", ---4x -[0x40] = "||dppsXrvmu", -[0x41] = "||dppdXrvmu", -[0x42] = "||mpsadbwXrvmu", -[0x44] = "||pclmulqdqXrvmu", -[0x46] = "||perm2i128Xrvmu", -[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb", -[0x4c] = "||pblendvbXrvmb", ---6x -[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu", -[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu", -[0xdf] = "||aeskeygenassistXrmu", -}, -} - --- Map for VMX/SVM opcodes 0F 01 C0-FF (sgdt group with register operands). -local map_opcvm = { -[0xc1]="vmcall",[0xc2]="vmlaunch",[0xc3]="vmresume",[0xc4]="vmxoff", -[0xc8]="monitor",[0xc9]="mwait", -[0xd8]="vmrun",[0xd9]="vmmcall",[0xda]="vmload",[0xdb]="vmsave", -[0xdc]="stgi",[0xdd]="clgi",[0xde]="skinit",[0xdf]="invlpga", -[0xf8]="swapgs",[0xf9]="rdtscp", -} - --- Map for FP opcodes. And you thought stack machines are simple? -local map_opcfp = { --- D8-DF 00-BF: opcodes with a memory operand. --- D8 -[0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm", -"fldFm",nil,"fstFm","fstpFm","fldenvVm","fldcwWm","fnstenvVm","fnstcwWm", --- DA -"fiaddDm","fimulDm","ficomDm","ficompDm", -"fisubDm","fisubrDm","fidivDm","fidivrDm", --- DB -"fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp", --- DC -"faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm", --- DD -"fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm", --- DE -"fiaddWm","fimulWm","ficomWm","ficompWm", -"fisubWm","fisubrWm","fidivWm","fidivrWm", --- DF -"fildWm","fisttpWm","fistWm","fistpWm", -"fbld twordFmp","fildQm","fbstp twordFmp","fistpQm", --- xx C0-FF: opcodes with a pseudo-register operand. --- D8 -"faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf", --- D9 -"fldFf","fxchFf",{"fnop"},nil, -{"fchs","fabs",nil,nil,"ftst","fxam"}, -{"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"}, -{"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"}, -{"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"}, --- DA -"fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil, --- DB -"fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf", -{nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil, --- DC -"fadd toFf","fmul toFf",nil,nil, -"fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf", --- DD -"ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil, --- DE -"faddpFf","fmulpFf",nil,{nil,"fcompp"}, -"fsubrpFf","fsubpFf","fdivrpFf","fdivpFf", --- DF -nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil, -} -assert(map_opcfp[126] == "fcomipFf") - --- Map for opcode groups. The subkey is sp from the ModRM byte. -local map_opcgroup = { - arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" }, - shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" }, - testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" }, - testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" }, - incb = { "inc", "dec" }, - incd = { "inc", "dec", "callUmp", "$call farDmp", - "jmpUmp", "$jmp farDmp", "pushUm" }, - sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" }, - sgdt = { "vm*$sgdt", "vm*$sidt", "$lgdt", "vm*$lidt", - "smsw", nil, "lmsw", "vm*$invlpg" }, - bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" }, - cmpxchg = { nil, "sz*,cmpxchg8bQmp,cmpxchg16bXmp", nil, nil, - nil, nil, "vmptrld|vmxon|vmclear", "vmptrst" }, - pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" }, - pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" }, - pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" }, - pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" }, - fxsave = { "$fxsave", "$fxrstor", "$ldmxcsr", "$stmxcsr", - nil, "lfenceDp$", "mfenceDp$", "sfenceDp$clflush" }, - prefetch = { "prefetch", "prefetchw" }, - prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" }, -} - ------------------------------------------------------------------------------- - --- Maps for register names. -local map_regs = { - B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", - "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }, - B64 = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", - "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }, - W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", - "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" }, - D = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", - "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" }, - Q = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }, - M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", - "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext! - X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", - "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" }, - Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", - "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" }, -} -local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" } - --- Maps for size names. -local map_sz2n = { - B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32, -} -local map_sz2prefix = { - B = "byte", W = "word", D = "dword", - Q = "qword", - M = "qword", X = "xword", Y = "yword", - F = "dword", G = "qword", -- No need for sizes/register names for these two. -} - ------------------------------------------------------------------------------- - --- Output a nicely formatted line with an opcode and operands. -local function putop(ctx, text, operands) - local code, pos, hex = ctx.code, ctx.pos, "" - local hmax = ctx.hexdump - if hmax > 0 then - for i=ctx.start,pos-1 do - hex = hex..format("%02X", byte(code, i, i)) - end - if #hex > hmax then hex = sub(hex, 1, hmax)..". " - else hex = hex..rep(" ", hmax-#hex+2) end - end - if operands then text = text.." "..operands end - if ctx.o16 then text = "o16 "..text; ctx.o16 = false end - if ctx.a32 then text = "a32 "..text; ctx.a32 = false end - if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end - if ctx.rex then - local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "").. - (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "").. - (ctx.vexl and "l" or "") - if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end - if t ~= "" then text = ctx.rex.."."..t.." "..text - elseif ctx.rex == "vex" then text = "v"..text end - ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false - ctx.rex = false; ctx.vexl = false; ctx.vexv = false - end - if ctx.seg then - local text2, n = gsub(text, "%[", "["..ctx.seg..":") - if n == 0 then text = ctx.seg.." "..text else text = text2 end - ctx.seg = false - end - if ctx.lock then text = "lock "..text; ctx.lock = false end - local imm = ctx.imm - if imm then - local sym = ctx.symtab[imm] - if sym then text = text.."\t->"..sym end - end - ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text)) - ctx.mrm = false - ctx.vexv = false - ctx.start = pos - ctx.imm = nil -end - --- Clear all prefix flags. -local function clearprefixes(ctx) - ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false - ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false - ctx.rex = false; ctx.a32 = false; ctx.vexl = false -end - --- Fallback for incomplete opcodes at the end. -local function incomplete(ctx) - ctx.pos = ctx.stop+1 - clearprefixes(ctx) - return putop(ctx, "(incomplete)") -end - --- Fallback for unknown opcodes. -local function unknown(ctx) - clearprefixes(ctx) - return putop(ctx, "(unknown)") -end - --- Return an immediate of the specified size. -local function getimm(ctx, pos, n) - if pos+n-1 > ctx.stop then return incomplete(ctx) end - local code = ctx.code - if n == 1 then - local b1 = byte(code, pos, pos) - return b1 - elseif n == 2 then - local b1, b2 = byte(code, pos, pos+1) - return b1+b2*256 - else - local b1, b2, b3, b4 = byte(code, pos, pos+3) - local imm = b1+b2*256+b3*65536+b4*16777216 - ctx.imm = imm - return imm - end -end - --- Process pattern string and generate the operands. -local function putpat(ctx, name, pat) - local operands, regs, sz, mode, sp, rm, sc, rx, sdisp - local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl - - -- Chars used: 1DFGIMPQRSTUVWXYabcdfgijlmoprstuvwxyz - for p in gmatch(pat, ".") do - local x = nil - if p == "V" or p == "U" then - if ctx.rexw then sz = "Q"; ctx.rexw = false - elseif ctx.o16 then sz = "W"; ctx.o16 = false - elseif p == "U" and ctx.x64 then sz = "Q" - else sz = "D" end - regs = map_regs[sz] - elseif p == "T" then - if ctx.rexw then sz = "Q"; ctx.rexw = false else sz = "D" end - regs = map_regs[sz] - elseif p == "B" then - sz = "B" - regs = ctx.rex and map_regs.B64 or map_regs.B - elseif match(p, "[WDQMXYFG]") then - sz = p - if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end - regs = map_regs[sz] - elseif p == "P" then - sz = ctx.o16 and "X" or "M"; ctx.o16 = false - if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end - regs = map_regs[sz] - elseif p == "S" then - name = name..lower(sz) - elseif p == "s" then - local imm = getimm(ctx, pos, 1); if not imm then return end - x = imm <= 127 and format("+0x%02x", imm) - or format("-0x%02x", 256-imm) - pos = pos+1 - elseif p == "u" then - local imm = getimm(ctx, pos, 1); if not imm then return end - x = format("0x%02x", imm) - pos = pos+1 - elseif p == "b" then - local imm = getimm(ctx, pos, 1); if not imm then return end - x = regs[imm/16+1] - pos = pos+1 - elseif p == "w" then - local imm = getimm(ctx, pos, 2); if not imm then return end - x = format("0x%x", imm) - pos = pos+2 - elseif p == "o" then -- [offset] - if ctx.x64 then - local imm1 = getimm(ctx, pos, 4); if not imm1 then return end - local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end - x = format("[0x%08x%08x]", imm2, imm1) - pos = pos+8 - else - local imm = getimm(ctx, pos, 4); if not imm then return end - x = format("[0x%08x]", imm) - pos = pos+4 - end - elseif p == "i" or p == "I" then - local n = map_sz2n[sz] - if n == 8 and ctx.x64 and p == "I" then - local imm1 = getimm(ctx, pos, 4); if not imm1 then return end - local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end - x = format("0x%08x%08x", imm2, imm1) - else - if n == 8 then n = 4 end - local imm = getimm(ctx, pos, n); if not imm then return end - if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then - imm = (0xffffffff+1)-imm - x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm) - else - x = format(imm > 65535 and "0x%08x" or "0x%x", imm) - end - end - pos = pos+n - elseif p == "j" then - local n = map_sz2n[sz] - if n == 8 then n = 4 end - local imm = getimm(ctx, pos, n); if not imm then return end - if sz == "B" and imm > 127 then imm = imm-256 - elseif imm > 2147483647 then imm = imm-4294967296 end - pos = pos+n - imm = imm + pos + ctx.addr - if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end - ctx.imm = imm - if sz == "W" then - x = format("word 0x%04x", imm%65536) - elseif ctx.x64 then - local lo = imm % 0x1000000 - x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo) - else - x = "0x"..tohex(imm) - end - elseif p == "R" then - local r = byte(code, pos-1, pos-1)%8 - if ctx.rexb then r = r + 8; ctx.rexb = false end - x = regs[r+1] - elseif p == "a" then x = regs[1] - elseif p == "c" then x = "cl" - elseif p == "d" then x = "dx" - elseif p == "1" then x = "1" - else - if not mode then - mode = ctx.mrm - if not mode then - if pos > stop then return incomplete(ctx) end - mode = byte(code, pos, pos) - pos = pos+1 - end - rm = mode%8; mode = (mode-rm)/8 - sp = mode%8; mode = (mode-sp)/8 - sdisp = "" - if mode < 3 then - if rm == 4 then - if pos > stop then return incomplete(ctx) end - sc = byte(code, pos, pos) - pos = pos+1 - rm = sc%8; sc = (sc-rm)/8 - rx = sc%8; sc = (sc-rx)/8 - if ctx.rexx then rx = rx + 8; ctx.rexx = false end - if rx == 4 then rx = nil end - end - if mode > 0 or rm == 5 then - local dsz = mode - if dsz ~= 1 then dsz = 4 end - local disp = getimm(ctx, pos, dsz); if not disp then return end - if mode == 0 then rm = nil end - if rm or rx or (not sc and ctx.x64 and not ctx.a32) then - if dsz == 1 and disp > 127 then - sdisp = format("-0x%x", 256-disp) - elseif disp >= 0 and disp <= 0x7fffffff then - sdisp = format("+0x%x", disp) - else - sdisp = format("-0x%x", (0xffffffff+1)-disp) - end - else - sdisp = format(ctx.x64 and not ctx.a32 and - not (disp >= 0 and disp <= 0x7fffffff) - and "0xffffffff%08x" or "0x%08x", disp) - end - pos = pos+dsz - end - end - if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end - if ctx.rexr then sp = sp + 8; ctx.rexr = false end - end - if p == "m" then - if mode == 3 then x = regs[rm+1] - else - local aregs = ctx.a32 and map_regs.D or ctx.aregs - local srm, srx = "", "" - if rm then srm = aregs[rm+1] - elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end - ctx.a32 = false - if rx then - if rm then srm = srm.."+" end - srx = aregs[rx+1] - if sc > 0 then srx = srx.."*"..(2^sc) end - end - x = format("[%s%s%s]", srm, srx, sdisp) - end - if mode < 3 and - (not match(pat, "[aRrgp]") or match(pat, "t")) then -- Yuck. - x = map_sz2prefix[sz].." "..x - end - elseif p == "r" then x = regs[sp+1] - elseif p == "g" then x = map_segregs[sp+1] - elseif p == "p" then -- Suppress prefix. - elseif p == "f" then x = "st"..rm - elseif p == "x" then - if sp == 0 and ctx.lock and not ctx.x64 then - x = "CR8"; ctx.lock = false - else - x = "CR"..sp - end - elseif p == "v" then - if ctx.vexv then - x = regs[ctx.vexv+1]; ctx.vexv = false - end - elseif p == "y" then x = "DR"..sp - elseif p == "z" then x = "TR"..sp - elseif p == "l" then vexl = false - elseif p == "t" then - else - error("bad pattern `"..pat.."'") - end - end - if x then operands = operands and operands..", "..x or x end - end - ctx.pos = pos - return putop(ctx, name, operands) -end - --- Forward declaration. -local map_act - --- Fetch and cache MRM byte. -local function getmrm(ctx) - local mrm = ctx.mrm - if not mrm then - local pos = ctx.pos - if pos > ctx.stop then return nil end - mrm = byte(ctx.code, pos, pos) - ctx.pos = pos+1 - ctx.mrm = mrm - end - return mrm -end - --- Dispatch to handler depending on pattern. -local function dispatch(ctx, opat, patgrp) - if not opat then return unknown(ctx) end - if match(opat, "%|") then -- MMX/SSE variants depending on prefix. - local p - if ctx.rep then - p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)" - ctx.rep = false - elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false - else p = "^[^%|]*" end - opat = match(opat, p) - if not opat then return unknown(ctx) end --- ctx.rep = false; ctx.o16 = false - --XXX fails for 66 f2 0f 38 f1 06 crc32 eax,WORD PTR [esi] - --XXX remove in branches? - end - if match(opat, "%$") then -- reg$mem variants. - local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end - opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)") - if opat == "" then return unknown(ctx) end - end - if opat == "" then return unknown(ctx) end - local name, pat = match(opat, "^([a-z0-9 ]*)(.*)") - if pat == "" and patgrp then pat = patgrp end - return map_act[sub(pat, 1, 1)](ctx, name, pat) -end - --- Get a pattern from an opcode map and dispatch to handler. -local function dispatchmap(ctx, opcmap) - local pos = ctx.pos - local opat = opcmap[byte(ctx.code, pos, pos)] - pos = pos + 1 - ctx.pos = pos - return dispatch(ctx, opat) -end - --- Map for action codes. The key is the first char after the name. -map_act = { - -- Simple opcodes without operands. - [""] = function(ctx, name, pat) - return putop(ctx, name) - end, - - -- Operand size chars fall right through. - B = putpat, W = putpat, D = putpat, Q = putpat, - V = putpat, U = putpat, T = putpat, - M = putpat, X = putpat, P = putpat, - F = putpat, G = putpat, Y = putpat, - - -- Collect prefixes. - [":"] = function(ctx, name, pat) - ctx[pat == ":" and name or sub(pat, 2)] = name - if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes. - end, - - -- Chain to special handler specified by name. - ["*"] = function(ctx, name, pat) - return map_act[name](ctx, name, sub(pat, 2)) - end, - - -- Use named subtable for opcode group. - ["!"] = function(ctx, name, pat) - local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end - return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2)) - end, - - -- o16,o32[,o64] variants. - sz = function(ctx, name, pat) - if ctx.o16 then ctx.o16 = false - else - pat = match(pat, ",(.*)") - if ctx.rexw then - local p = match(pat, ",(.*)") - if p then pat = p; ctx.rexw = false end - end - end - pat = match(pat, "^[^,]*") - return dispatch(ctx, pat) - end, - - -- Two-byte opcode dispatch. - opc2 = function(ctx, name, pat) - return dispatchmap(ctx, map_opc2) - end, - - -- Three-byte opcode dispatch. - opc3 = function(ctx, name, pat) - return dispatchmap(ctx, map_opc3[pat]) - end, - - -- VMX/SVM dispatch. - vm = function(ctx, name, pat) - return dispatch(ctx, map_opcvm[ctx.mrm]) - end, - - -- Floating point opcode dispatch. - fp = function(ctx, name, pat) - local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end - local rm = mrm%8 - local idx = pat*8 + ((mrm-rm)/8)%8 - if mrm >= 192 then idx = idx + 64 end - local opat = map_opcfp[idx] - if type(opat) == "table" then opat = opat[rm+1] end - return dispatch(ctx, opat) - end, - - -- REX prefix. - rex = function(ctx, name, pat) - if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed. - for p in gmatch(pat, ".") do ctx["rex"..p] = true end - ctx.rex = "rex" - end, - - -- VEX prefix. - vex = function(ctx, name, pat) - if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed. - ctx.rex = "vex" - local pos = ctx.pos - if ctx.mrm then - ctx.mrm = nil - pos = pos-1 - end - local b = byte(ctx.code, pos, pos) - if not b then return incomplete(ctx) end - pos = pos+1 - if b < 128 then ctx.rexr = true end - local m = 1 - if pat == "3" then - m = b%32; b = (b-m)/32 - local nb = b%2; b = (b-nb)/2 - if nb == 0 then ctx.rexb = true end - local nx = b%2; b = (b-nx)/2 - if nx == 0 then ctx.rexx = true end - b = byte(ctx.code, pos, pos) - if not b then return incomplete(ctx) end - pos = pos+1 - if b >= 128 then ctx.rexw = true end - end - ctx.pos = pos - local map - if m == 1 then map = map_opc2 - elseif m == 2 then map = map_opc3["38"] - elseif m == 3 then map = map_opc3["3a"] - else return unknown(ctx) end - local p = b%4; b = (b-p)/4 - if p == 1 then ctx.o16 = "o16" - elseif p == 2 then ctx.rep = "rep" - elseif p == 3 then ctx.rep = "repne" end - local l = b%2; b = (b-l)/2 - if l ~= 0 then ctx.vexl = true end - ctx.vexv = (-1-b)%16 - return dispatchmap(ctx, map) - end, - - -- Special case for nop with REX prefix. - nop = function(ctx, name, pat) - return dispatch(ctx, ctx.rex and pat or "nop") - end, - - -- Special case for 0F 77. - emms = function(ctx, name, pat) - if ctx.rex ~= "vex" then - return putop(ctx, "emms") - elseif ctx.vexl then - ctx.vexl = false - return putop(ctx, "zeroall") - else - return putop(ctx, "zeroupper") - end - end, -} - ------------------------------------------------------------------------------- - --- Disassemble a block of code. -local function disass_block(ctx, ofs, len) - if not ofs then ofs = 0 end - local stop = len and ofs+len or #ctx.code - ofs = ofs + 1 - ctx.start = ofs - ctx.pos = ofs - ctx.stop = stop - ctx.imm = nil - ctx.mrm = false - clearprefixes(ctx) - while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end - if ctx.pos ~= ctx.start then incomplete(ctx) end -end - --- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). -local function create(code, addr, out) - local ctx = {} - ctx.code = code - ctx.addr = (addr or 0) - 1 - ctx.out = out or io.write - ctx.symtab = {} - ctx.disass = disass_block - ctx.hexdump = 16 - ctx.x64 = false - ctx.map1 = map_opc1_32 - ctx.aregs = map_regs.D - return ctx -end - -local function create64(code, addr, out) - local ctx = create(code, addr, out) - ctx.x64 = true - ctx.map1 = map_opc1_64 - ctx.aregs = map_regs.Q - return ctx -end - --- Simple API: disassemble code (a string) at address and output via out. -local function disass(code, addr, out) - create(code, addr, out):disass() -end - -local function disass64(code, addr, out) - create64(code, addr, out):disass() -end - --- Return register name for RID. -local function regname(r) - if r < 8 then return map_regs.D[r+1] end - return map_regs.X[r-7] -end - -local function regname64(r) - if r < 16 then return map_regs.Q[r+1] end - return map_regs.X[r-15] -end - --- Public module functions. -return { - create = create, - create64 = create64, - disass = disass, - disass64 = disass64, - regname = regname, - regname64 = regname64 -} - diff --git a/Assets/LuaFramework/Luajit/jit/dis_x86.lua.meta b/Assets/LuaFramework/Luajit/jit/dis_x86.lua.meta deleted file mode 100644 index a4c55e6..0000000 --- a/Assets/LuaFramework/Luajit/jit/dis_x86.lua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 676a7cf93973aa444ad7cf6d244083d8 -DefaultImporter: - userData: diff --git a/Assets/LuaFramework/Luajit/jit/dump.lua b/Assets/LuaFramework/Luajit/jit/dump.lua deleted file mode 100644 index 9d8330e..0000000 --- a/Assets/LuaFramework/Luajit/jit/dump.lua +++ /dev/null @@ -1,707 +0,0 @@ ----------------------------------------------------------------------------- --- LuaJIT compiler dump module. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- --- This module can be used to debug the JIT compiler itself. It dumps the --- code representations and structures used in various compiler stages. --- --- Example usage: --- --- luajit -jdump -e "local x=0; for i=1,1e6 do x=x+i end; print(x)" --- luajit -jdump=im -e "for i=1,1000 do for j=1,1000 do end end" | less -R --- luajit -jdump=is myapp.lua | less -R --- luajit -jdump=-b myapp.lua --- luajit -jdump=+aH,myapp.html myapp.lua --- luajit -jdump=ixT,myapp.dump myapp.lua --- --- The first argument specifies the dump mode. The second argument gives --- the output file name. Default output is to stdout, unless the environment --- variable LUAJIT_DUMPFILE is set. The file is overwritten every time the --- module is started. --- --- Different features can be turned on or off with the dump mode. If the --- mode starts with a '+', the following features are added to the default --- set of features; a '-' removes them. Otherwise the features are replaced. --- --- The following dump features are available (* marks the default): --- --- * t Print a line for each started, ended or aborted trace (see also -jv). --- * b Dump the traced bytecode. --- * i Dump the IR (intermediate representation). --- r Augment the IR with register/stack slots. --- s Dump the snapshot map. --- * m Dump the generated machine code. --- x Print each taken trace exit. --- X Print each taken trace exit and the contents of all registers. --- a Print the IR of aborted traces, too. --- --- The output format can be set with the following characters: --- --- T Plain text output. --- A ANSI-colored text output --- H Colorized HTML + CSS output. --- --- The default output format is plain text. It's set to ANSI-colored text --- if the COLORTERM variable is set. Note: this is independent of any output --- redirection, which is actually considered a feature. --- --- You probably want to use less -R to enjoy viewing ANSI-colored text from --- a pipe or a file. Add this to your ~/.bashrc: export LESS="-R" --- ------------------------------------------------------------------------------- - --- Cache some library functions and objects. -local jit = require("jit") -assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") -local jutil = require("jit.util") -local vmdef = require("jit.vmdef") -local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc -local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek -local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap -local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr -local bit = require("bit") -local band, shl, shr, tohex = bit.band, bit.lshift, bit.rshift, bit.tohex -local sub, gsub, format = string.sub, string.gsub, string.format -local byte, char, rep = string.byte, string.char, string.rep -local type, tostring = type, tostring -local stdout, stderr = io.stdout, io.stderr - --- Load other modules on-demand. -local bcline, disass - --- Active flag, output file handle and dump mode. -local active, out, dumpmode - ------------------------------------------------------------------------------- - -local symtabmt = { __index = false } -local symtab = {} -local nexitsym = 0 - --- Fill nested symbol table with per-trace exit stub addresses. -local function fillsymtab_tr(tr, nexit) - local t = {} - symtabmt.__index = t - if jit.arch == "mips" or jit.arch == "mipsel" then - t[traceexitstub(tr, 0)] = "exit" - return - end - for i=0,nexit-1 do - local addr = traceexitstub(tr, i) - if addr < 0 then addr = addr + 2^32 end - t[addr] = tostring(i) - end - local addr = traceexitstub(tr, nexit) - if addr then t[addr] = "stack_check" end -end - --- Fill symbol table with trace exit stub addresses. -local function fillsymtab(tr, nexit) - local t = symtab - if nexitsym == 0 then - local ircall = vmdef.ircall - for i=0,#ircall do - local addr = ircalladdr(i) - if addr ~= 0 then - if addr < 0 then addr = addr + 2^32 end - t[addr] = ircall[i] - end - end - end - if nexitsym == 1000000 then -- Per-trace exit stubs. - fillsymtab_tr(tr, nexit) - elseif nexit > nexitsym then -- Shared exit stubs. - for i=nexitsym,nexit-1 do - local addr = traceexitstub(i) - if addr == nil then -- Fall back to per-trace exit stubs. - fillsymtab_tr(tr, nexit) - setmetatable(symtab, symtabmt) - nexit = 1000000 - break - end - if addr < 0 then addr = addr + 2^32 end - t[addr] = tostring(i) - end - nexitsym = nexit - end - return t -end - -local function dumpwrite(s) - out:write(s) -end - --- Disassemble machine code. -local function dump_mcode(tr) - local info = traceinfo(tr) - if not info then return end - local mcode, addr, loop = tracemc(tr) - if not mcode then return end - if not disass then disass = require("jit.dis_"..jit.arch) end - if addr < 0 then addr = addr + 2^32 end - out:write("---- TRACE ", tr, " mcode ", #mcode, "\n") - local ctx = disass.create(mcode, addr, dumpwrite) - ctx.hexdump = 0 - ctx.symtab = fillsymtab(tr, info.nexit) - if loop ~= 0 then - symtab[addr+loop] = "LOOP" - ctx:disass(0, loop) - out:write("->LOOP:\n") - ctx:disass(loop, #mcode-loop) - symtab[addr+loop] = nil - else - ctx:disass(0, #mcode) - end -end - ------------------------------------------------------------------------------- - -local irtype_text = { - [0] = "nil", - "fal", - "tru", - "lud", - "str", - "p32", - "thr", - "pro", - "fun", - "p64", - "cdt", - "tab", - "udt", - "flt", - "num", - "i8 ", - "u8 ", - "i16", - "u16", - "int", - "u32", - "i64", - "u64", - "sfp", -} - -local colortype_ansi = { - [0] = "%s", - "%s", - "%s", - "\027[36m%s\027[m", - "\027[32m%s\027[m", - "%s", - "\027[1m%s\027[m", - "%s", - "\027[1m%s\027[m", - "%s", - "\027[33m%s\027[m", - "\027[31m%s\027[m", - "\027[36m%s\027[m", - "\027[34m%s\027[m", - "\027[34m%s\027[m", - "\027[35m%s\027[m", - "\027[35m%s\027[m", - "\027[35m%s\027[m", - "\027[35m%s\027[m", - "\027[35m%s\027[m", - "\027[35m%s\027[m", - "\027[35m%s\027[m", - "\027[35m%s\027[m", - "\027[35m%s\027[m", -} - -local function colorize_text(s, t) - return s -end - -local function colorize_ansi(s, t) - return format(colortype_ansi[t], s) -end - -local irtype_ansi = setmetatable({}, - { __index = function(tab, t) - local s = colorize_ansi(irtype_text[t], t); tab[t] = s; return s; end }) - -local html_escape = { ["<"] = "<", [">"] = ">", ["&"] = "&", } - -local function colorize_html(s, t) - s = gsub(s, "[<>&]", html_escape) - return format('%s', irtype_text[t], s) -end - -local irtype_html = setmetatable({}, - { __index = function(tab, t) - local s = colorize_html(irtype_text[t], t); tab[t] = s; return s; end }) - -local header_html = [[ - -]] - -local colorize, irtype - --- Lookup tables to convert some literals into names. -local litname = { - ["SLOAD "] = setmetatable({}, { __index = function(t, mode) - local s = "" - if band(mode, 1) ~= 0 then s = s.."P" end - if band(mode, 2) ~= 0 then s = s.."F" end - if band(mode, 4) ~= 0 then s = s.."T" end - if band(mode, 8) ~= 0 then s = s.."C" end - if band(mode, 16) ~= 0 then s = s.."R" end - if band(mode, 32) ~= 0 then s = s.."I" end - t[mode] = s - return s - end}), - ["XLOAD "] = { [0] = "", "R", "V", "RV", "U", "RU", "VU", "RVU", }, - ["CONV "] = setmetatable({}, { __index = function(t, mode) - local s = irtype[band(mode, 31)] - s = irtype[band(shr(mode, 5), 31)].."."..s - if band(mode, 0x800) ~= 0 then s = s.." sext" end - local c = shr(mode, 14) - if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end - t[mode] = s - return s - end}), - ["FLOAD "] = vmdef.irfield, - ["FREF "] = vmdef.irfield, - ["FPMATH"] = vmdef.irfpm, - ["BUFHDR"] = { [0] = "RESET", "APPEND" }, - ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, -} - -local function ctlsub(c) - if c == "\n" then return "\\n" - elseif c == "\r" then return "\\r" - elseif c == "\t" then return "\\t" - else return format("\\%03d", byte(c)) - end -end - -local function fmtfunc(func, pc) - local fi = funcinfo(func, pc) - if fi.loc then - return fi.loc - elseif fi.ffid then - return vmdef.ffnames[fi.ffid] - elseif fi.addr then - return format("C:%x", fi.addr) - else - return "(?)" - end -end - -local function formatk(tr, idx) - local k, t, slot = tracek(tr, idx) - local tn = type(k) - local s - if tn == "number" then - if k == 2^52+2^51 then - s = "bias" - else - s = format("%+.14g", k) - end - elseif tn == "string" then - s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub)) - elseif tn == "function" then - s = fmtfunc(k) - elseif tn == "table" then - s = format("{%p}", k) - elseif tn == "userdata" then - if t == 12 then - s = format("userdata:%p", k) - else - s = format("[%p]", k) - if s == "[0x00000000]" then s = "NULL" end - end - elseif t == 21 then -- int64_t - s = sub(tostring(k), 1, -3) - if sub(s, 1, 1) ~= "-" then s = "+"..s end - else - s = tostring(k) -- For primitives. - end - s = colorize(format("%-4s", s), t) - if slot then - s = format("%s @%d", s, slot) - end - return s -end - -local function printsnap(tr, snap) - local n = 2 - for s=0,snap[1]-1 do - local sn = snap[n] - if shr(sn, 24) == s then - n = n + 1 - local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS - if ref < 0 then - out:write(formatk(tr, ref)) - elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM - out:write(colorize(format("%04d/%04d", ref, ref+1), 14)) - else - local m, ot, op1, op2 = traceir(tr, ref) - out:write(colorize(format("%04d", ref), band(ot, 31))) - end - out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME - else - out:write("---- ") - end - end - out:write("]\n") -end - --- Dump snapshots (not interleaved with IR). -local function dump_snap(tr) - out:write("---- TRACE ", tr, " snapshots\n") - for i=0,1000000000 do - local snap = tracesnap(tr, i) - if not snap then break end - out:write(format("#%-3d %04d [ ", i, snap[0])) - printsnap(tr, snap) - end -end - --- Return a register name or stack slot for a rid/sp location. -local function ridsp_name(ridsp, ins) - if not disass then disass = require("jit.dis_"..jit.arch) end - local rid, slot = band(ridsp, 0xff), shr(ridsp, 8) - if rid == 253 or rid == 254 then - return (slot == 0 or slot == 255) and " {sink" or format(" {%04d", ins-slot) - end - if ridsp > 255 then return format("[%x]", slot*4) end - if rid < 128 then return disass.regname(rid) end - return "" -end - --- Dump CALL* function ref and return optional ctype. -local function dumpcallfunc(tr, ins) - local ctype - if ins > 0 then - local m, ot, op1, op2 = traceir(tr, ins) - if band(ot, 31) == 0 then -- nil type means CARG(func, ctype). - ins = op1 - ctype = formatk(tr, op2) - end - end - if ins < 0 then - out:write(format("[0x%x](", tonumber((tracek(tr, ins))))) - else - out:write(format("%04d (", ins)) - end - return ctype -end - --- Recursively gather CALL* args and dump them. -local function dumpcallargs(tr, ins) - if ins < 0 then - out:write(formatk(tr, ins)) - else - local m, ot, op1, op2 = traceir(tr, ins) - local oidx = 6*shr(ot, 8) - local op = sub(vmdef.irnames, oidx+1, oidx+6) - if op == "CARG " then - dumpcallargs(tr, op1) - if op2 < 0 then - out:write(" ", formatk(tr, op2)) - else - out:write(" ", format("%04d", op2)) - end - else - out:write(format("%04d", ins)) - end - end -end - --- Dump IR and interleaved snapshots. -local function dump_ir(tr, dumpsnap, dumpreg) - local info = traceinfo(tr) - if not info then return end - local nins = info.nins - out:write("---- TRACE ", tr, " IR\n") - local irnames = vmdef.irnames - local snapref = 65536 - local snap, snapno - if dumpsnap then - snap = tracesnap(tr, 0) - snapref = snap[0] - snapno = 0 - end - for ins=1,nins do - if ins >= snapref then - if dumpreg then - out:write(format(".... SNAP #%-3d [ ", snapno)) - else - out:write(format(".... SNAP #%-3d [ ", snapno)) - end - printsnap(tr, snap) - snapno = snapno + 1 - snap = tracesnap(tr, snapno) - snapref = snap and snap[0] or 65536 - end - local m, ot, op1, op2, ridsp = traceir(tr, ins) - local oidx, t = 6*shr(ot, 8), band(ot, 31) - local op = sub(irnames, oidx+1, oidx+6) - if op == "LOOP " then - if dumpreg then - out:write(format("%04d ------------ LOOP ------------\n", ins)) - else - out:write(format("%04d ------ LOOP ------------\n", ins)) - end - elseif op ~= "NOP " and op ~= "CARG " and - (dumpreg or op ~= "RENAME") then - local rid = band(ridsp, 255) - if dumpreg then - out:write(format("%04d %-6s", ins, ridsp_name(ridsp, ins))) - else - out:write(format("%04d ", ins)) - end - out:write(format("%s%s %s %s ", - (rid == 254 or rid == 253) and "}" or - (band(ot, 128) == 0 and " " or ">"), - band(ot, 64) == 0 and " " or "+", - irtype[t], op)) - local m1, m2 = band(m, 3), band(m, 3*4) - if sub(op, 1, 4) == "CALL" then - local ctype - if m2 == 1*4 then -- op2 == IRMlit - out:write(format("%-10s (", vmdef.ircall[op2])) - else - ctype = dumpcallfunc(tr, op2) - end - if op1 ~= -1 then dumpcallargs(tr, op1) end - out:write(")") - if ctype then out:write(" ctype ", ctype) end - elseif op == "CNEW " and op2 == -1 then - out:write(formatk(tr, op1)) - elseif m1 ~= 3 then -- op1 != IRMnone - if op1 < 0 then - out:write(formatk(tr, op1)) - else - out:write(format(m1 == 0 and "%04d" or "#%-3d", op1)) - end - if m2 ~= 3*4 then -- op2 != IRMnone - if m2 == 1*4 then -- op2 == IRMlit - local litn = litname[op] - if litn and litn[op2] then - out:write(" ", litn[op2]) - elseif op == "UREFO " or op == "UREFC " then - out:write(format(" #%-3d", shr(op2, 8))) - else - out:write(format(" #%-3d", op2)) - end - elseif op2 < 0 then - out:write(" ", formatk(tr, op2)) - else - out:write(format(" %04d", op2)) - end - end - end - out:write("\n") - end - end - if snap then - if dumpreg then - out:write(format(".... SNAP #%-3d [ ", snapno)) - else - out:write(format(".... SNAP #%-3d [ ", snapno)) - end - printsnap(tr, snap) - end -end - ------------------------------------------------------------------------------- - -local recprefix = "" -local recdepth = 0 - --- Format trace error message. -local function fmterr(err, info) - if type(err) == "number" then - if type(info) == "function" then info = fmtfunc(info) end - err = format(vmdef.traceerr[err], info) - end - return err -end - --- Dump trace states. -local function dump_trace(what, tr, func, pc, otr, oex) - if what == "stop" or (what == "abort" and dumpmode.a) then - if dumpmode.i then dump_ir(tr, dumpmode.s, dumpmode.r and what == "stop") - elseif dumpmode.s then dump_snap(tr) end - if dumpmode.m then dump_mcode(tr) end - end - if what == "start" then - if dumpmode.H then out:write('
\n') end
-    out:write("---- TRACE ", tr, " ", what)
-    if otr then out:write(" ", otr, "/", oex) end
-    out:write(" ", fmtfunc(func, pc), "\n")
-  elseif what == "stop" or what == "abort" then
-    out:write("---- TRACE ", tr, " ", what)
-    if what == "abort" then
-      out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
-    else
-      local info = traceinfo(tr)
-      local link, ltype = info.link, info.linktype
-      if link == tr or link == 0 then
-	out:write(" -> ", ltype, "\n")
-      elseif ltype == "root" then
-	out:write(" -> ", link, "\n")
-      else
-	out:write(" -> ", link, " ", ltype, "\n")
-      end
-    end
-    if dumpmode.H then out:write("
\n\n") else out:write("\n") end - else - if what == "flush" then symtab, nexitsym = {}, 0 end - out:write("---- TRACE ", what, "\n\n") - end - out:flush() -end - --- Dump recorded bytecode. -local function dump_record(tr, func, pc, depth, callee) - if depth ~= recdepth then - recdepth = depth - recprefix = rep(" .", depth) - end - local line - if pc >= 0 then - line = bcline(func, pc, recprefix) - if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end - else - line = "0000 "..recprefix.." FUNCC \n" - callee = func - end - if pc <= 0 then - out:write(sub(line, 1, -2), " ; ", fmtfunc(func), "\n") - else - out:write(line) - end - if pc >= 0 and band(funcbc(func, pc), 0xff) < 16 then -- ORDER BC - out:write(bcline(func, pc+1, recprefix)) -- Write JMP for cond. - end -end - ------------------------------------------------------------------------------- - --- Dump taken trace exits. -local function dump_texit(tr, ex, ngpr, nfpr, ...) - out:write("---- TRACE ", tr, " exit ", ex, "\n") - if dumpmode.X then - local regs = {...} - if jit.arch == "x64" then - for i=1,ngpr do - out:write(format(" %016x", regs[i])) - if i % 4 == 0 then out:write("\n") end - end - else - for i=1,ngpr do - out:write(" ", tohex(regs[i])) - if i % 8 == 0 then out:write("\n") end - end - end - if jit.arch == "mips" or jit.arch == "mipsel" then - for i=1,nfpr,2 do - out:write(format(" %+17.14g", regs[ngpr+i])) - if i % 8 == 7 then out:write("\n") end - end - else - for i=1,nfpr do - out:write(format(" %+17.14g", regs[ngpr+i])) - if i % 4 == 0 then out:write("\n") end - end - end - end -end - ------------------------------------------------------------------------------- - --- Detach dump handlers. -local function dumpoff() - if active then - active = false - jit.attach(dump_texit) - jit.attach(dump_record) - jit.attach(dump_trace) - if out and out ~= stdout and out ~= stderr then out:close() end - out = nil - end -end - --- Open the output file and attach dump handlers. -local function dumpon(opt, outfile) - if active then dumpoff() end - - local colormode = os.getenv("COLORTERM") and "A" or "T" - if opt then - opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end) - end - - local m = { t=true, b=true, i=true, m=true, } - if opt and opt ~= "" then - local o = sub(opt, 1, 1) - if o ~= "+" and o ~= "-" then m = {} end - for i=1,#opt do m[sub(opt, i, i)] = (o ~= "-") end - end - dumpmode = m - - if m.t or m.b or m.i or m.s or m.m then - jit.attach(dump_trace, "trace") - end - if m.b then - jit.attach(dump_record, "record") - if not bcline then bcline = require("jit.bc").line end - end - if m.x or m.X then - jit.attach(dump_texit, "texit") - end - - if not outfile then outfile = os.getenv("LUAJIT_DUMPFILE") end - if outfile then - out = outfile == "-" and stdout or assert(io.open(outfile, "w")) - else - out = stdout - end - - m[colormode] = true - if colormode == "A" then - colorize = colorize_ansi - irtype = irtype_ansi - elseif colormode == "H" then - colorize = colorize_html - irtype = irtype_html - out:write(header_html) - else - colorize = colorize_text - irtype = irtype_text - end - - active = true -end - --- Public module functions. -return { - on = dumpon, - off = dumpoff, - start = dumpon -- For -j command line option. -} - diff --git a/Assets/LuaFramework/Luajit/jit/dump.lua.meta b/Assets/LuaFramework/Luajit/jit/dump.lua.meta deleted file mode 100644 index 5d559ce..0000000 --- a/Assets/LuaFramework/Luajit/jit/dump.lua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 029c25a735609054d81dee95957d1fc8 -DefaultImporter: - userData: diff --git a/Assets/LuaFramework/Luajit/jit/v.lua b/Assets/LuaFramework/Luajit/jit/v.lua deleted file mode 100644 index 60c8b05..0000000 --- a/Assets/LuaFramework/Luajit/jit/v.lua +++ /dev/null @@ -1,170 +0,0 @@ ----------------------------------------------------------------------------- --- Verbose mode of the LuaJIT compiler. --- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. --- Released under the MIT license. See Copyright Notice in luajit.h ----------------------------------------------------------------------------- --- --- This module shows verbose information about the progress of the --- JIT compiler. It prints one line for each generated trace. This module --- is useful to see which code has been compiled or where the compiler --- punts and falls back to the interpreter. --- --- Example usage: --- --- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end" --- luajit -jv=myapp.out myapp.lua --- --- Default output is to stderr. To redirect the output to a file, pass a --- filename as an argument (use '-' for stdout) or set the environment --- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the --- module is started. --- --- The output from the first example should look like this: --- --- [TRACE 1 (command line):1 loop] --- [TRACE 2 (1/3) (command line):1 -> 1] --- --- The first number in each line is the internal trace number. Next are --- the file name ('(command line)') and the line number (':1') where the --- trace has started. Side traces also show the parent trace number and --- the exit number where they are attached to in parentheses ('(1/3)'). --- An arrow at the end shows where the trace links to ('-> 1'), unless --- it loops to itself. --- --- In this case the inner loop gets hot and is traced first, generating --- a root trace. Then the last exit from the 1st trace gets hot, too, --- and triggers generation of the 2nd trace. The side trace follows the --- path along the outer loop and *around* the inner loop, back to its --- start, and then links to the 1st trace. Yes, this may seem unusual, --- if you know how traditional compilers work. Trace compilers are full --- of surprises like this -- have fun! :-) --- --- Aborted traces are shown like this: --- --- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50] --- --- Don't worry -- trace aborts are quite common, even in programs which --- can be fully compiled. The compiler may retry several times until it --- finds a suitable trace. --- --- Of course this doesn't work with features that are not-yet-implemented --- (NYI error messages). The VM simply falls back to the interpreter. This --- may not matter at all if the particular trace is not very high up in --- the CPU usage profile. Oh, and the interpreter is quite fast, too. --- --- Also check out the -jdump module, which prints all the gory details. --- ------------------------------------------------------------------------------- - --- Cache some library functions and objects. -local jit = require("jit") -assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") -local jutil = require("jit.util") -local vmdef = require("jit.vmdef") -local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo -local type, format = type, string.format -local stdout, stderr = io.stdout, io.stderr - --- Active flag and output file handle. -local active, out - ------------------------------------------------------------------------------- - -local startloc, startex - -local function fmtfunc(func, pc) - local fi = funcinfo(func, pc) - if fi.loc then - return fi.loc - elseif fi.ffid then - return vmdef.ffnames[fi.ffid] - elseif fi.addr then - return format("C:%x", fi.addr) - else - return "(?)" - end -end - --- Format trace error message. -local function fmterr(err, info) - if type(err) == "number" then - if type(info) == "function" then info = fmtfunc(info) end - err = format(vmdef.traceerr[err], info) - end - return err -end - --- Dump trace states. -local function dump_trace(what, tr, func, pc, otr, oex) - if what == "start" then - startloc = fmtfunc(func, pc) - startex = otr and "("..otr.."/"..oex..") " or "" - else - if what == "abort" then - local loc = fmtfunc(func, pc) - if loc ~= startloc then - out:write(format("[TRACE --- %s%s -- %s at %s]\n", - startex, startloc, fmterr(otr, oex), loc)) - else - out:write(format("[TRACE --- %s%s -- %s]\n", - startex, startloc, fmterr(otr, oex))) - end - elseif what == "stop" then - local info = traceinfo(tr) - local link, ltype = info.link, info.linktype - if ltype == "interpreter" then - out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n", - tr, startex, startloc)) - elseif ltype == "stitch" then - out:write(format("[TRACE %3s %s%s %s %s]\n", - tr, startex, startloc, ltype, fmtfunc(func, pc))) - elseif link == tr or link == 0 then - out:write(format("[TRACE %3s %s%s %s]\n", - tr, startex, startloc, ltype)) - elseif ltype == "root" then - out:write(format("[TRACE %3s %s%s -> %d]\n", - tr, startex, startloc, link)) - else - out:write(format("[TRACE %3s %s%s -> %d %s]\n", - tr, startex, startloc, link, ltype)) - end - else - out:write(format("[TRACE %s]\n", what)) - end - out:flush() - end -end - ------------------------------------------------------------------------------- - --- Detach dump handlers. -local function dumpoff() - if active then - active = false - jit.attach(dump_trace) - if out and out ~= stdout and out ~= stderr then out:close() end - out = nil - end -end - --- Open the output file and attach dump handlers. -local function dumpon(outfile) - if active then dumpoff() end - if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end - if outfile then - out = outfile == "-" and stdout or assert(io.open(outfile, "w")) - else - out = stderr - end - jit.attach(dump_trace, "trace") - active = true -end - --- Public module functions. -return { - on = dumpon, - off = dumpoff, - start = dumpon -- For -j command line option. -} - diff --git a/Assets/LuaFramework/Luajit/jit/v.lua.meta b/Assets/LuaFramework/Luajit/jit/v.lua.meta deleted file mode 100644 index fd94880..0000000 --- a/Assets/LuaFramework/Luajit/jit/v.lua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 724b205f5019d9449807abad317fbb38 -DefaultImporter: - userData: diff --git a/Assets/LuaFramework/Luajit/jit/vmdef.lua b/Assets/LuaFramework/Luajit/jit/vmdef.lua deleted file mode 100644 index 4660660..0000000 --- a/Assets/LuaFramework/Luajit/jit/vmdef.lua +++ /dev/null @@ -1,331 +0,0 @@ --- This is a generated file. DO NOT EDIT! - -module(...) - -bcnames = "ISLT ISGE ISLE ISGT ISEQV ISNEV ISEQS ISNES ISEQN ISNEN ISEQP ISNEP ISTC ISFC IST ISF MOV NOT UNM LEN ADDVN SUBVN MULVN DIVVN MODVN ADDNV SUBNV MULNV DIVNV MODNV ADDVV SUBVV MULVV DIVVV MODVV POW CAT KSTR KCDATAKSHORTKNUM KPRI KNIL UGET USETV USETS USETN USETP UCLO FNEW TNEW TDUP GGET GSET TGETV TGETS TGETB TSETV TSETS TSETB TSETM CALLM CALL CALLMTCALLT ITERC ITERN VARG ISNEXTRETM RET RET0 RET1 FORI JFORI FORL IFORL JFORL ITERL IITERLJITERLLOOP ILOOP JLOOP JMP FUNCF IFUNCFJFUNCFFUNCV IFUNCVJFUNCVFUNCC FUNCCW" - -irnames = "LT GE LE GT ULT UGE ULE UGT EQ NE ABC RETF NOP BASE PVAL GCSTEPHIOP LOOP USE PHI RENAMEKPRI KINT KGC KPTR KKPTR KNULL KNUM KINT64KSLOT BNOT BSWAP BAND BOR BXOR BSHL BSHR BSAR BROL BROR ADD SUB MUL DIV MOD POW NEG ABS ATAN2 LDEXP MIN MAX FPMATHADDOV SUBOV MULOV AREF HREFK HREF NEWREFUREFO UREFC FREF STRREFALOAD HLOAD ULOAD FLOAD XLOAD SLOAD VLOAD ASTOREHSTOREUSTOREFSTOREXSTORESNEW XSNEW TNEW TDUP CNEW CNEWI TBAR OBAR XBAR CONV TOBIT TOSTR STRTO CALLN CALLL CALLS CALLXSCARG " - -irfpm = { [0]="floor", "ceil", "trunc", "sqrt", "exp", "exp2", "log", "log2", "log10", "sin", "cos", "tan", "other", } - -irfield = { [0]="str.len", "func.env", "func.pc", "tab.meta", "tab.array", "tab.node", "tab.asize", "tab.hmask", "tab.nomm", "udata.meta", "udata.udtype", "udata.file", "cdata.ctypeid", "cdata.ptr", "cdata.int", "cdata.int64", "cdata.int64_4", } - -ircall = { -[0]="lj_str_cmp", -"lj_str_new", -"lj_strscan_num", -"lj_str_fromint", -"lj_str_fromnum", -"lj_tab_new1", -"lj_tab_dup", -"lj_tab_newkey", -"lj_tab_len", -"lj_gc_step_jit", -"lj_gc_barrieruv", -"lj_mem_newgco", -"lj_math_random_step", -"lj_vm_modi", -"sinh", -"cosh", -"tanh", -"fputc", -"fwrite", -"fflush", -"lj_vm_floor", -"lj_vm_ceil", -"lj_vm_trunc", -"sqrt", -"exp", -"lj_vm_exp2", -"log", -"lj_vm_log2", -"log10", -"sin", -"cos", -"tan", -"lj_vm_powi", -"pow", -"atan2", -"ldexp", -"lj_vm_tobit", -"softfp_add", -"softfp_sub", -"softfp_mul", -"softfp_div", -"softfp_cmp", -"softfp_i2d", -"softfp_d2i", -"softfp_ui2d", -"softfp_f2d", -"softfp_d2ui", -"softfp_d2f", -"softfp_i2f", -"softfp_ui2f", -"softfp_f2i", -"softfp_f2ui", -"fp64_l2d", -"fp64_ul2d", -"fp64_l2f", -"fp64_ul2f", -"fp64_d2l", -"fp64_d2ul", -"fp64_f2l", -"fp64_f2ul", -"lj_carith_divi64", -"lj_carith_divu64", -"lj_carith_modi64", -"lj_carith_modu64", -"lj_carith_powi64", -"lj_carith_powu64", -"lj_cdata_setfin", -"strlen", -"memcpy", -"memset", -"lj_vm_errno", -"lj_carith_mul64", -} - -traceerr = { -[0]="error thrown or hook called during recording", -"trace too long", -"trace too deep", -"too many snapshots", -"blacklisted", -"NYI: bytecode %d", -"leaving loop in root trace", -"inner loop in root trace", -"loop unroll limit reached", -"bad argument type", -"JIT compilation disabled for function", -"call unroll limit reached", -"down-recursion, restarting", -"NYI: C function %p", -"NYI: FastFunc %s", -"NYI: unsupported variant of FastFunc %s", -"NYI: return to lower frame", -"store with nil or NaN key", -"missing metamethod", -"looping index lookup", -"NYI: mixed sparse/dense table", -"symbol not in cache", -"NYI: unsupported C type conversion", -"NYI: unsupported C function type", -"guard would always fail", -"too many PHIs", -"persistent type instability", -"failed to allocate mcode memory", -"machine code too long", -"hit mcode limit (retrying)", -"too many spill slots", -"inconsistent register allocation", -"NYI: cannot assemble IR instruction %d", -"NYI: PHI shuffling too complex", -"NYI: register coalescing too complex", -} - -ffnames = { -[0]="Lua", -"C", -"assert", -"type", -"next", -"pairs", -"ipairs_aux", -"ipairs", -"getmetatable", -"setmetatable", -"getfenv", -"setfenv", -"rawget", -"rawset", -"rawequal", -"unpack", -"select", -"tonumber", -"tostring", -"error", -"pcall", -"xpcall", -"loadfile", -"load", -"loadstring", -"dofile", -"gcinfo", -"collectgarbage", -"newproxy", -"print", -"coroutine.status", -"coroutine.running", -"coroutine.create", -"coroutine.yield", -"coroutine.resume", -"coroutine.wrap_aux", -"coroutine.wrap", -"math.abs", -"math.floor", -"math.ceil", -"math.sqrt", -"math.log10", -"math.exp", -"math.sin", -"math.cos", -"math.tan", -"math.asin", -"math.acos", -"math.atan", -"math.sinh", -"math.cosh", -"math.tanh", -"math.frexp", -"math.modf", -"math.deg", -"math.rad", -"math.log", -"math.atan2", -"math.pow", -"math.fmod", -"math.ldexp", -"math.min", -"math.max", -"math.random", -"math.randomseed", -"bit.tobit", -"bit.bnot", -"bit.bswap", -"bit.lshift", -"bit.rshift", -"bit.arshift", -"bit.rol", -"bit.ror", -"bit.band", -"bit.bor", -"bit.bxor", -"bit.tohex", -"string.len", -"string.byte", -"string.char", -"string.sub", -"string.rep", -"string.reverse", -"string.lower", -"string.upper", -"string.dump", -"string.find", -"string.match", -"string.gmatch_aux", -"string.gmatch", -"string.gsub", -"string.format", -"table.foreachi", -"table.foreach", -"table.getn", -"table.maxn", -"table.insert", -"table.remove", -"table.concat", -"table.sort", -"io.method.close", -"io.method.read", -"io.method.write", -"io.method.flush", -"io.method.seek", -"io.method.setvbuf", -"io.method.lines", -"io.method.__gc", -"io.method.__tostring", -"io.open", -"io.popen", -"io.tmpfile", -"io.close", -"io.read", -"io.write", -"io.flush", -"io.input", -"io.output", -"io.lines", -"io.type", -"os.execute", -"os.remove", -"os.rename", -"os.tmpname", -"os.getenv", -"os.exit", -"os.clock", -"os.date", -"os.time", -"os.difftime", -"os.setlocale", -"debug.getregistry", -"debug.getmetatable", -"debug.setmetatable", -"debug.getfenv", -"debug.setfenv", -"debug.getinfo", -"debug.getlocal", -"debug.setlocal", -"debug.getupvalue", -"debug.setupvalue", -"debug.upvalueid", -"debug.upvaluejoin", -"debug.sethook", -"debug.gethook", -"debug.debug", -"debug.traceback", -"jit.on", -"jit.off", -"jit.flush", -"jit.status", -"jit.attach", -"jit.util.funcinfo", -"jit.util.funcbc", -"jit.util.funck", -"jit.util.funcuvname", -"jit.util.traceinfo", -"jit.util.traceir", -"jit.util.tracek", -"jit.util.tracesnap", -"jit.util.tracemc", -"jit.util.traceexitstub", -"jit.util.ircalladdr", -"jit.opt.start", -"ffi.meta.__index", -"ffi.meta.__newindex", -"ffi.meta.__eq", -"ffi.meta.__len", -"ffi.meta.__lt", -"ffi.meta.__le", -"ffi.meta.__concat", -"ffi.meta.__call", -"ffi.meta.__add", -"ffi.meta.__sub", -"ffi.meta.__mul", -"ffi.meta.__div", -"ffi.meta.__mod", -"ffi.meta.__pow", -"ffi.meta.__unm", -"ffi.meta.__tostring", -"ffi.meta.__pairs", -"ffi.meta.__ipairs", -"ffi.clib.__index", -"ffi.clib.__newindex", -"ffi.clib.__gc", -"ffi.callback.free", -"ffi.callback.set", -"ffi.cdef", -"ffi.new", -"ffi.cast", -"ffi.typeof", -"ffi.istype", -"ffi.sizeof", -"ffi.alignof", -"ffi.offsetof", -"ffi.errno", -"ffi.string", -"ffi.copy", -"ffi.fill", -"ffi.abi", -"ffi.metatype", -"ffi.gc", -"ffi.load", -} - diff --git a/Assets/LuaFramework/Luajit/jit/vmdef.lua.meta b/Assets/LuaFramework/Luajit/jit/vmdef.lua.meta deleted file mode 100644 index dc73d35..0000000 --- a/Assets/LuaFramework/Luajit/jit/vmdef.lua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: cd5259d2e7ff79146978231b90c15d75 -DefaultImporter: - userData: diff --git a/Assets/LuaFramework/Luajit/lua51.dll b/Assets/LuaFramework/Luajit/lua51.dll deleted file mode 100644 index eba797be79ada57e63436874fca513ba10bfd413..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 375296 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ìX#r$L{qe?-KrGePVP*^xOPDJ^J@3f=+GzI<w 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¥PzTn*2xc2m=f_!EJ6z)H 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
pJ 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%0Acc0l@i8W!q>i`dv17Tu*i4{esiy-c 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 UMb;hWd+>JXh5zUG|5gk9FE4xK2><{9 diff --git a/Assets/LuaFramework/Luajit/luajit.exe b/Assets/LuaFramework/Luajit/luajit.exe deleted file mode 100644 index 27d70270d7c23403b86343fbdaea0bedf33821e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86016 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 - /// 集成自LuaFileUtils,重写里面的ReadFile, - /// - public class LuaLoader : LuaFileUtils - { - // LuaBundle列表 - private List luaBundleList = new List(); - - // Use this for initialization - public LuaLoader() { - instance = this; - beZip = AppConst.LuaBundleMode; - } - - ///

- /// 添加打入Lua代码的AssetBundle - /// - /// 加入的Bundle - public void AddBundle(AssetBundle bundle) - { - if (null != bundle) - { - luaBundleList.Add(bundle); - GameLogger.Log("LuaLoader.AddBunle = " + bundle.name); - } - } - - /// - /// 当LuaVM加载Lua文件的时候,这里就会被调用, - /// 用户可以自定义加载行为,只要返回byte[]即可。 - /// - /// - /// - public override byte[] ReadFile(string fileName) - { - if (!beZip) - { - string path = FindFile(fileName); - byte[] str = null; - - if (!string.IsNullOrEmpty(path) && File.Exists(path)) - { -#if !UNITY_WEBPLAYER - str = File.ReadAllBytes(path); -#else - throw new LuaException("can't run in web platform, please switch to other platform"); -#endif - } - - return str; - } - else - { - return ReadBytesFromAssetBundle(fileName); - } - } - - /// - /// 从AssetBundle读取lua代码 - /// - /// lua脚本名 - /// - private byte[] ReadBytesFromAssetBundle(string fileName) - { - fileName = "assets/luabundle/" + fileName; - - TextAsset luaCode = null; - for (int i = 0, cnt = luaBundleList.Count; i < cnt; ++i) - { - var bundle = luaBundleList[i]; - luaCode = bundle.LoadAsset(fileName + ".bytes"); - if (null != luaCode) - break; - else - { - // require过来的没有.lua后缀 - var extension = Path.GetExtension(fileName); - if (string.IsNullOrEmpty(extension)) - { - luaCode = bundle.LoadAsset(fileName + ".lua.bytes"); - if (null != luaCode) - break; - } - } - } - if (null != luaCode) - { - // 因为打Lua AssetBundle之前对lua脚本做了加密,所以这里需要进行解密 - var butes = AESEncrypt.Decrypt(luaCode.bytes); - return butes; - } - else - { - Debug.LogError("LuaFileUtils.ReadBytesFromAssetBundle Error, null == luaCode, fileName:" + fileName); - return null; - } - } - } -} \ No newline at end of file diff --git a/Assets/LuaFramework/Scripts/ConstDefine/AppConst.cs b/Assets/LuaFramework/Scripts/ConstDefine/AppConst.cs index 0c8ac21..47b1e56 100644 --- a/Assets/LuaFramework/Scripts/ConstDefine/AppConst.cs +++ b/Assets/LuaFramework/Scripts/ConstDefine/AppConst.cs @@ -6,32 +6,31 @@ using System.Collections.Generic; namespace LuaFramework { public class AppConst { -#if UNITY_EDITOR - // Lua代码AssetBundle模式 - public const bool LuaBundleMode = false; -#else - public const bool LuaBundleMode = true; -#endif + // 调试模式-用于内部测试 + public const bool DebugMode = false; + + // 帧数 + public const int TimerInterval = 1; // 游戏帧频 public const int GameFrameRate = 30; - // 素材目录 - public const string AssetDir = "StreamingAssets"; + // 应用程序名称 + public const string AppName = "LuaFramework"; // 热更列表url,用于热更 public const string HOT_UPDATE_URL = "http://localhost:18800/HotUpdateServer/update_list.json"; - // 日志文件dir,用于存放本地日志 - public const string LOG_UPLOAD_DIR = "{0}/output_{1}.log"; // url,用于上传日志 public const string LOG_UPLOAD_URL = "http://127.0.0.1:18800/LogServer/upload_log.php"; - // 游戏服务器IP - public const string SocketAddress = "127.0.0.1"; - // 游戏服务器端口 - public const int SocketPort = 18801; + // 用户id + public static string UserId = string.Empty; + // Socket服务器端口 + public static int SocketPort = 0; + // Socket服务器地址 + public static string SocketAddress = string.Empty; public static string FrameworkRoot { get { - return Application.dataPath + "/LuaFramework"; + return Application.dataPath + "/" + AppName; } } } diff --git a/Assets/LuaFramework/Scripts/ConstDefine/ManagerName.cs b/Assets/LuaFramework/Scripts/ConstDefine/ManagerName.cs index 972c672..8d6db9d 100644 --- a/Assets/LuaFramework/Scripts/ConstDefine/ManagerName.cs +++ b/Assets/LuaFramework/Scripts/ConstDefine/ManagerName.cs @@ -1,16 +1,6 @@ -using UnityEngine; -using System.Collections; - -namespace LuaFramework { +namespace LuaFramework +{ public class ManagerName { - public const string Lua = "LuaManager"; - public const string Game = "GameManager"; - public const string Timer = "TimeManager"; - public const string Sound = "SoundManager"; - public const string Panel = "PanelManager"; - public const string Network = "NetworkManager"; - public const string Resource = "ResourceManager"; - public const string Thread = "ThreadManager"; - public const string ObjectPool = "ObjectPoolManager"; + public const string Network = "Network"; } } \ No newline at end of file diff --git a/Assets/LuaFramework/Scripts/Controller/Command/SocketCommand.cs b/Assets/LuaFramework/Scripts/Controller/Command/SocketCommand.cs deleted file mode 100644 index 6844b10..0000000 --- a/Assets/LuaFramework/Scripts/Controller/Command/SocketCommand.cs +++ /dev/null @@ -1,16 +0,0 @@ -using UnityEngine; -using System.Collections; -using System.Collections.Generic; -using LuaFramework; - -public class SocketCommand : ControllerCommand { - - public override void Execute(IMessage message) { - object data = message.Body; - if (data == null) return; - KeyValuePair buffer = (KeyValuePair)data; - switch (buffer.Key) { - default: Util.CallMethod("Network", "OnSocket", buffer.Key, buffer.Value); break; - } - } -} diff --git a/Assets/LuaFramework/Scripts/Framework/AppFacade.cs b/Assets/LuaFramework/Scripts/Framework/AppFacade.cs index e5013dd..6030f0a 100644 --- a/Assets/LuaFramework/Scripts/Framework/AppFacade.cs +++ b/Assets/LuaFramework/Scripts/Framework/AppFacade.cs @@ -6,39 +6,42 @@ using LuaFramework; public class AppFacade : Facade { - private static AppFacade _instance; + private static AppFacade mInstance; public AppFacade() : base() { } - public static AppFacade Instance + public static AppFacade instance { - get{ - if (_instance == null) { - _instance = new AppFacade(); + get + { + if (mInstance == null) + { + mInstance = new AppFacade(); } - return _instance; + return mInstance; } } - override protected void InitFramework() - { - base.InitFramework(); - } + private bool mIsStartUp = false; + private string mShareKey; + private string mShareData; /// /// 启动框架 /// public void StartUp() { - //-----------------关联命令----------------------- - RegisterCommand(NotiConst.DISPATCH_MESSAGE, typeof(SocketCommand)); + if (!Util.CheckEnvironment()) + { + return; + } + + mIsStartUp = true; - //-----------------初始化管理器----------------------- - AddManager(ManagerName.Lua); - AddManager(ManagerName.Network); - AddManager(ManagerName.Game); + LuaInterface.LuaFileUtils.Instance.Init(); + NetworkManager.GetInstance(); } } diff --git a/Assets/LuaFramework/Scripts/Framework/Core/Base.cs b/Assets/LuaFramework/Scripts/Framework/Core/Base.cs index 7a5ebfb..9385989 100644 --- a/Assets/LuaFramework/Scripts/Framework/Core/Base.cs +++ b/Assets/LuaFramework/Scripts/Framework/Core/Base.cs @@ -1,57 +1,18 @@ using UnityEngine; -using System.Collections; -using LuaFramework; -using System.Collections.Generic; -public class Base : MonoBehaviour { +public class Base : MonoBehaviour +{ private AppFacade m_Facade; - private LuaManager m_LuaMgr; - private NetworkManager m_NetMgr; - /// - /// 注册消息 - /// - /// - /// - protected void RegisterMessage(IView view, List messages) { - if (messages == null || messages.Count == 0) return; - Controller.Instance.RegisterViewCommand(view, messages.ToArray()); - } - - /// - /// 移除消息 - /// - /// - /// - protected void RemoveMessage(IView view, List messages) { - if (messages == null || messages.Count == 0) return; - Controller.Instance.RemoveViewCommand(view, messages.ToArray()); - } - - protected AppFacade facade { - get { - if (m_Facade == null) { - m_Facade = AppFacade.Instance; + protected AppFacade facade + { + get + { + if (m_Facade == null) + { + m_Facade = AppFacade.instance; } return m_Facade; } } - - protected LuaManager LuaManager { - get { - if (m_LuaMgr == null) { - m_LuaMgr = facade.GetManager(ManagerName.Lua); - } - return m_LuaMgr; - } - } - - protected NetworkManager NetManager { - get { - if (m_NetMgr == null) { - m_NetMgr = facade.GetManager(ManagerName.Network); - } - return m_NetMgr; - } - } } diff --git a/Assets/LuaFramework/Scripts/Framework/Core/Facade.cs b/Assets/LuaFramework/Scripts/Framework/Core/Facade.cs index acb9751..404bb72 100644 --- a/Assets/LuaFramework/Scripts/Framework/Core/Facade.cs +++ b/Assets/LuaFramework/Scripts/Framework/Core/Facade.cs @@ -6,16 +6,8 @@ using System; using System.Collections.Generic; using UnityEngine; -/// -/// 事件命令 -/// -public class ControllerCommand : ICommand { - public virtual void Execute(IMessage message) { - } -} - public class Facade { - protected IController m_controller; + // protected IController m_controller; static GameObject m_GameManager; static Dictionary m_Managers = new Dictionary(); @@ -29,41 +21,6 @@ public class Facade { } protected Facade() { - InitFramework(); - } - protected virtual void InitFramework() { - if (m_controller != null) return; - m_controller = Controller.Instance; - } - - public virtual void RegisterCommand(string commandName, Type commandType) { - m_controller.RegisterCommand(commandName, commandType); - } - - public virtual void RemoveCommand(string commandName) { - m_controller.RemoveCommand(commandName); - } - - public virtual bool HasCommand(string commandName) { - return m_controller.HasCommand(commandName); - } - - public void RegisterMultiCommand(Type commandType, params string[] commandNames) { - int count = commandNames.Length; - for (int i = 0; i < count; i++) { - RegisterCommand(commandNames[i], commandType); - } - } - - public void RemoveMultiCommand(params string[] commandName) { - int count = commandName.Length; - for (int i = 0; i < count; i++) { - RemoveCommand(commandName[i]); - } - } - - public void SendMessageCommand(string message, object body = null) { - m_controller.ExecuteCommand(new Message(message, body)); } /// @@ -101,6 +58,21 @@ public class Facade { return (T)manager; } + /// + /// 获取系统管理器forlua + /// + /// + /// + public object GetManager(string typeName) + { + object obj = null; + if (m_Managers.TryGetValue(typeName, out obj)) + { + return obj; + } + return null; + } + /// /// 删除管理器 /// diff --git a/Assets/LuaFramework/Scripts/Framework/Core/Manager.cs b/Assets/LuaFramework/Scripts/Framework/Core/Manager.cs deleted file mode 100644 index 2b1e3b3..0000000 --- a/Assets/LuaFramework/Scripts/Framework/Core/Manager.cs +++ /dev/null @@ -1,16 +0,0 @@ -using UnityEngine; -using System.Collections; -using LuaFramework; - -public class Manager : Base, IManager { - - // Use this for initialization - void Start () { - - } - - // Update is called once per frame - void Update () { - - } -} diff --git a/Assets/LuaFramework/Scripts/Framework/Core/Message.cs b/Assets/LuaFramework/Scripts/Framework/Core/Message.cs deleted file mode 100644 index cec5b40..0000000 --- a/Assets/LuaFramework/Scripts/Framework/Core/Message.cs +++ /dev/null @@ -1,94 +0,0 @@ -/* - LuaFramework Code By Jarjin lee -*/ - -using System; -public class Message : IMessage -{ - public Message(string name) - : this(name, null, null) - { } - - public Message(string name, object body) - : this(name, body, null) - { } - - public Message(string name, object body, string type) - { - m_name = name; - m_body = body; - m_type = type; - } - - /// - /// Get the string representation of the Notification instance - /// - /// The string representation of the Notification instance - public override string ToString() - { - string msg = "Notification Name: " + Name; - msg += "\nBody:" + ((Body == null) ? "null" : Body.ToString()); - msg += "\nType:" + ((Type == null) ? "null" : Type); - return msg; - } - - /// - /// The name of the Notification instance - /// - public virtual string Name - { - get { return m_name; } - } - - /// - /// The body of the Notification instance - /// - /// This accessor is thread safe - public virtual object Body - { - get - { - // Setting and getting of reference types is atomic, no need to lock here - return m_body; - } - set - { - // Setting and getting of reference types is atomic, no need to lock here - m_body = value; - } - } - - /// - /// The type of the Notification instance - /// - /// This accessor is thread safe - public virtual string Type - { - get - { - // Setting and getting of reference types is atomic, no need to lock here - return m_type; - } - set - { - // Setting and getting of reference types is atomic, no need to lock here - m_type = value; - } - } - - /// - /// The name of the notification instance - /// - private string m_name; - - /// - /// The type of the notification instance - /// - private string m_type; - - /// - /// The body of the notification instance - /// - private object m_body; -} - diff --git a/Assets/LuaFramework/Scripts/Framework/Core/View.cs b/Assets/LuaFramework/Scripts/Framework/Core/View.cs deleted file mode 100644 index c81ac17..0000000 --- a/Assets/LuaFramework/Scripts/Framework/Core/View.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; -using System; -using System.Collections; -using System.Collections.Generic; -using LuaInterface; -using LuaFramework; - -public class View : Base, IView { - public virtual void OnMessage(IMessage message) { - } -} diff --git a/Assets/LuaFramework/Scripts/Manager/GameManager.cs b/Assets/LuaFramework/Scripts/Manager/GameManager.cs deleted file mode 100644 index 9975ecb..0000000 --- a/Assets/LuaFramework/Scripts/Manager/GameManager.cs +++ /dev/null @@ -1,63 +0,0 @@ -using UnityEngine; -using System; -using System.Collections; -using System.Collections.Generic; -using LuaInterface; -using System.Reflection; -using System.IO; - - -namespace LuaFramework { - public class GameManager : Manager - { - protected static bool initialize = false; - private List downloadFiles = new List(); - - /// - /// 初始化游戏管理器 - /// - void Awake() - { - Init(); - } - - /// - /// 初始化 - /// - void Init() - { - DontDestroyOnLoad(gameObject); //防止销毁自己 - - Screen.sleepTimeout = SleepTimeout.NeverSleep; - Application.targetFrameRate = AppConst.GameFrameRate; - OnInitialize(); - } - - void OnInitialize() - { - LuaManager.InitStart(); - LuaManager.DoFile("Logic/Game"); //加载游戏 - LuaManager.DoFile("Logic/Network"); //加载网络 - NetManager.OnInit(); //初始化网络 - Util.CallMethod("Game", "OnInitOK"); //初始化完成 - - initialize = true; - } - - /// - /// 析构函数 - /// - void OnDestroy() - { - if (NetManager != null) - { - NetManager.Unload(); - } - if (LuaManager != null) - { - LuaManager.Close(); - } - Debug.Log("GameManager was destroyed"); - } - } -} \ No newline at end of file diff --git a/Assets/LuaFramework/Scripts/Manager/GameManager.cs.meta b/Assets/LuaFramework/Scripts/Manager/GameManager.cs.meta deleted file mode 100644 index 1e78e53..0000000 --- a/Assets/LuaFramework/Scripts/Manager/GameManager.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b1545d35cb5d31e469cff9e3dbc576e9 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/LuaFramework/Scripts/Manager/Interface/ITimerBehaviour.cs b/Assets/LuaFramework/Scripts/Manager/Interface/ITimerBehaviour.cs deleted file mode 100644 index 9904997..0000000 --- a/Assets/LuaFramework/Scripts/Manager/Interface/ITimerBehaviour.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; -using System.Collections; - -namespace LuaFramework { - public interface ITimerBehaviour { - void TimerUpdate(); - } -} \ No newline at end of file diff --git a/Assets/LuaFramework/Scripts/Manager/Interface/ITimerBehaviour.cs.meta b/Assets/LuaFramework/Scripts/Manager/Interface/ITimerBehaviour.cs.meta deleted file mode 100644 index f008b12..0000000 --- a/Assets/LuaFramework/Scripts/Manager/Interface/ITimerBehaviour.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: fbedf5a696e61a1408b87a90afcb33f1 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/LuaFramework/Scripts/Manager/LuaManager.cs b/Assets/LuaFramework/Scripts/Manager/LuaManager.cs index def184e..0da5f76 100644 --- a/Assets/LuaFramework/Scripts/Manager/LuaManager.cs +++ b/Assets/LuaFramework/Scripts/Manager/LuaManager.cs @@ -1,40 +1,59 @@ -using UnityEngine; -using System.Collections; +#define LUA_VERSION_5_3 + +using UnityEngine; using LuaInterface; +using System; + +namespace LuaFramework +{ + public class LuaManager + { + private static LuaManager mInstance; + public static LuaManager instance + { + get + { + if (mInstance == null) + { + mInstance = new LuaManager(); + } + return mInstance; + } + } -namespace LuaFramework { - public class LuaManager : Manager { private LuaState lua; - private LuaLoader loader; - private LuaLooper loop = null; - // Use this for initialization - void Awake() { - loader = new LuaLoader(); + private LuaManager() + { lua = new LuaState(); +#if LUA_VERSION_5_3 +#else + LuaDLL.tolua_setflag(ToLuaFlags.USE_INT64, true); + LuaDLL.tolua_setflag(ToLuaFlags.FLAG_UINT64, true); +#endif this.OpenLibs(); lua.LuaSetTop(0); LuaBinder.Bind(lua); - DelegateFactory.Init(); - LuaCoroutine.Register(lua, this); - } + OpenBindLib(); - public void InitStart() { - InitLuaPath(); - InitLuaBundle(); - this.lua.Start(); //启动LUAVM - this.StartMain(); - this.StartLooper(); } - void StartLooper() { - loop = gameObject.AddComponent(); - loop.luaState = lua; + public void InitStart(Action okCb) + { + this.lua.Start(); //启动LUAVM + this.StartMain(() => + { + // 初始化lualooper + LuaLooper.instance.OnInit(lua); + if (null != okCb) + okCb(); + }); } //cjson 比较特殊,只new了一个table,没有注册库,这里注册一下 - protected void OpenCJson() { + protected void OpenCJson() + { lua.LuaGetField(LuaIndexes.LUA_REGISTRYINDEX, "_LOADED"); lua.OpenLibs(LuaDLL.luaopen_cjson); lua.LuaSetField(-2, "cjson"); @@ -43,7 +62,8 @@ namespace LuaFramework { lua.LuaSetField(-2, "cjson.safe"); } - void StartMain() { + void StartMain(Action okCb) + { lua.DoFile("Main.lua"); LuaFunction main = lua.GetFunction("Main"); @@ -55,44 +75,58 @@ namespace LuaFramework { /// /// 初始化加载第三方库 /// - void OpenLibs() { + void OpenLibs() + { lua.OpenLibs(LuaDLL.luaopen_pb); lua.OpenLibs(LuaDLL.luaopen_sproto_core); lua.OpenLibs(LuaDLL.luaopen_protobuf_c); lua.OpenLibs(LuaDLL.luaopen_lpeg); +#if LUA_VERSION_5_3 + lua.OpenLibs(LuaDLL.luaopen_bit32); +#else lua.OpenLibs(LuaDLL.luaopen_bit); +#endif lua.OpenLibs(LuaDLL.luaopen_socket_core); this.OpenCJson(); } /// - /// 初始化Lua代码加载路径 + /// 打开绑定的library /// - void InitLuaPath() { - string rootPath = AppConst.FrameworkRoot; - lua.AddSearchPath(rootPath + "/Lua"); - lua.AddSearchPath(rootPath + "/ToLua/Lua"); + void OpenBindLib() + { + lua.BeginModule(null); + lua.BeginModule("LuaFramework"); + WrapCSObj.Register(lua); + lua.EndModule(); + lua.EndModule(); } - /// - /// 初始化LuaBundle - /// - void InitLuaBundle() { - if (loader.beZip) { - loader.AddBundle(ResourceMgr.instance.GetAssetBundle("lua_update.bundle")); - loader.AddBundle(ResourceMgr.instance.GetAssetBundle("lua.bundle")); - } + public LuaTable CreateLuaTable(int narr = 0, int nec = 0) + { + lua.LuaCreateTable(narr, nec); + LuaTable tab = lua.CheckLuaTable(-1); + + return tab; } - public void DoFile(string filename) { - lua.DoFile(filename); + public LuaTable CheckLuaTable(int stackPos) + { + return lua.CheckLuaTable(stackPos); + } + + public object[] DoFile(string filename) + { + return lua.DoFile(filename); } // Update is called once per frame - public object[] CallFunction(string funcName, params object[] args) { + public object[] CallFunction(string funcName, params object[] args) + { LuaFunction func = lua.GetFunction(funcName); - if (func != null) { + if (func != null) + { return func.LazyCall(args); } return null; @@ -103,17 +137,49 @@ namespace LuaFramework { return lua.GetFunction(funcName, logMiss); } - public void LuaGC() { + /// + /// 获取lua函数debug字符串 + /// + /// + public string GetLuaFunDebugStr() + { + return lua.GetLuaFunDebugStr(); + } + + public void LuaGC() + { lua.LuaGC(LuaGCOptions.LUA_GCCOLLECT); } - public void Close() { - loop.Destroy(); - loop = null; + public void Close() + { + if (lua != null) + { + lua.Dispose(); + lua = null; + } + } + + public LuaState GetState() + { + return lua; + } - lua.Dispose(); - lua = null; - loader = null; + /// + /// 重载脚本 + /// + /// lua文件列表 + public void ReloadLuaFiles(string[] luaFileNames) + { + for (int i = 0; i < luaFileNames.Length; i++) + { + string fileName = luaFileNames[i]; + if (!string.IsNullOrEmpty(fileName) && !fileName.StartsWith("--")) + { + lua.DoFile(fileName); + GameLogger.LogGreen("Reload: " + fileName); + } + } } } } \ No newline at end of file diff --git a/Assets/LuaFramework/Scripts/Manager/NetworkManager.cs b/Assets/LuaFramework/Scripts/Manager/NetworkManager.cs index 805ea73..8e4707c 100644 --- a/Assets/LuaFramework/Scripts/Manager/NetworkManager.cs +++ b/Assets/LuaFramework/Scripts/Manager/NetworkManager.cs @@ -1,37 +1,72 @@ -using UnityEngine; -using System; -using System.Collections; using System.Collections.Generic; using LuaInterface; -namespace LuaFramework { - public class NetworkManager : Manager { - private SocketClient socket; - static readonly object m_lockObject = new object(); - static Queue> mEvents = new Queue>(); - - SocketClient SocketClient { - get { - if (socket == null) - socket = new SocketClient(); - return socket; +namespace LuaFramework +{ + /// + /// 与Lua对接的网络管理器 + /// + public class NetworkManager : INetStateListener + { + private static NetworkManager mInstance; + public static NetworkManager instance + { + get + { + if (mInstance == null) + mInstance = new NetworkManager(); + return mInstance; } } + public static NetworkManager GetInstance() + { + if (mInstance == null) + mInstance = new NetworkManager(); + return mInstance; + } - void Awake() { - Init(); + private NetworkManager() + { + // 网络状态监听 + ClientNet.instance.AddNetStateListener(this); } - void Init() { - SocketClient.OnRegister(); + // 协议处理tag:proto定义的标记 |flag 0:只C#层处理(不需要添加),1:lua C#共同处理 2:只lua 处理 + static Dictionary mS2CDic = new Dictionary(); + static Dictionary mC2SDic = new Dictionary(); + static Dictionary mSession2ProtoDic = new Dictionary(); + + // 收到服务器消息后的lua处理方法 + private static LuaFunction OnRequestDataFunc = null; + public static void SetOnRequestDataFunc(LuaFunction requestFunc) + { + OnRequestDataFunc = requestFunc; + } + private static LuaFunction OnResponseDataFunc = null; + public static void SetOnResponseDataFunc(LuaFunction responseFunc) + { + OnResponseDataFunc = responseFunc; } - public void OnInit() { - CallMethod("Start"); + [NoToLuaAttribute] + public void OnInit() + { + CallMethod("OnInit"); + OnRequestDataFunc = Util.GetFunction("Network", "OnRequestDataFunc"); + OnResponseDataFunc = Util.GetFunction("Network", "OnResponseDataFunc"); } - public void Unload() { - CallMethod("Unload"); + [NoToLuaAttribute] + public void Unload() + { + if (OnRequestDataFunc != null) + { + OnRequestDataFunc.Dispose(); + } + if (OnResponseDataFunc != null) + { + OnResponseDataFunc.Dispose(); + } } /// @@ -41,45 +76,56 @@ namespace LuaFramework { return Util.CallMethod("Network", func, args); } - ///------------------------------------------------------------------------------------ - public static void AddEvent(int _event, ByteBuffer data) { - lock (m_lockObject) { - mEvents.Enqueue(new KeyValuePair(_event, data)); - } - } - /// - /// 交给Command,这里不想关心发给谁。 + /// 当网络状态改变时 /// - void Update() { - if (mEvents.Count > 0) { - while (mEvents.Count > 0) { - KeyValuePair _event = mEvents.Dequeue(); - facade.SendMessageCommand(NotiConst.DISPATCH_MESSAGE, _event); - } - } + /// + /// + [NoToLuaAttribute] + public void OnNetStateChanged(NetState state, object param = null) + { + // 通知lua脚本 + CallMethod("OnNetStateChanged", (int)state, param); } /// - /// 发送链接请求 + /// 发送的时候缓存一下session /// - public void SendConnect() { - SocketClient.SendConnect(); + /// + /// + public static void OnSendData(int session, string protoName) + { + mSession2ProtoDic.Add(session, protoName); } - /// - /// 发送SOCKET消息 - /// - public void SendMessage(ByteBuffer buffer) { - SocketClient.SendMessage(buffer); + [NoToLuaAttribute] + public static bool OnRequestData(SpStream spStream, int type) + { + int processType = 0; + if (mS2CDic.TryGetValue(type, out processType)) + { + if (processType > 0) + { + if (OnRequestDataFunc != null) + { + object[] objs = OnRequestDataFunc.LazyCall(spStream, spStream.Length); + if (objs != null && objs.Length >= 1) + { + return (bool)objs[0]; + } + } + return processType <= 1; + } + } + return true; } /// /// 析构函数 /// - new void OnDestroy() { - SocketClient.OnRemove(); - Debug.Log("~NetworkManager was destroy"); + [NoToLuaAttribute] + public void OnDestroy() { + GameLogger.Log("~NetworkManager was destroy"); } } } diff --git a/Assets/LuaFramework/Scripts/Network/HeartBeat.cs b/Assets/LuaFramework/Scripts/Network/HeartBeat.cs new file mode 100644 index 0000000..0cdc27e --- /dev/null +++ b/Assets/LuaFramework/Scripts/Network/HeartBeat.cs @@ -0,0 +1,69 @@ +using System; +using System.Threading; +using System.Collections; + +/// +/// 网络连接的心跳逻辑 +/// +public class HeartBeat +{ + public HeartBeat(RemoteConnection connection) + { + m_locker = new object(); + m_connection = connection; + } + + public void Start() + { + m_countNextSendTime = 0; + m_countNextRecvTime = 0; + m_timer = new Timer(callbackAfterPer5s, null, 1, 5000); + } + + public void Stop() + { + lock (m_locker) + { + if (m_timer != null) + { + m_timer.Dispose(); + m_timer = null; + } + } + } + + private void callbackAfterPer5s(Object state) + { + m_countNextSendTime+=5; + m_countNextRecvTime+=5; + + if (m_countNextSendTime >= SEND_HEARTBEAT_INTERVAL) + { + m_countNextSendTime = 0; + if (m_connection.isConnect) + m_connection.Send("heartbeat", null); + } + + int elapsed = getElapsedByTick(m_connection.lastRecvTick); + if (elapsed >= NETWORK_TIMOUT) + { + Stop(); + m_countNextRecvTime = 0; + m_connection.Disconnect(); + } + } + + private int getElapsedByTick(long tick) + { + TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - tick); + return (int)(ts.TotalSeconds); + } + + private int m_countNextSendTime, m_countNextRecvTime; + private Timer m_timer; + private object m_locker; + private RemoteConnection m_connection; + + private const int NETWORK_TIMOUT = 40; + private const int SEND_HEARTBEAT_INTERVAL = 15; +} diff --git a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_ParticleSystemWrap.cs.meta b/Assets/LuaFramework/Scripts/Network/HeartBeat.cs.meta similarity index 83% rename from Assets/LuaFramework/ToLua/BaseType/UnityEngine_ParticleSystemWrap.cs.meta rename to Assets/LuaFramework/Scripts/Network/HeartBeat.cs.meta index 08d992c..e984936 100644 --- a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_ParticleSystemWrap.cs.meta +++ b/Assets/LuaFramework/Scripts/Network/HeartBeat.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9f9577118422ed74fb9b6eb0daec4864 +guid: 6d5eff995ba2e654ca351478640955c7 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/LuaFramework/Scripts/Network/ProtoEncrypt.cs b/Assets/LuaFramework/Scripts/Network/ProtoEncrypt.cs new file mode 100644 index 0000000..ceb8cc9 --- /dev/null +++ b/Assets/LuaFramework/Scripts/Network/ProtoEncrypt.cs @@ -0,0 +1,226 @@ + +using UnityEngine; +using System.Security.Cryptography; +using System.IO; + +/// +/// 协议加密 +/// +public class ProtoEncrypt +{ + private readonly byte[] kPublicKey = { 0xc8, 0x3d, 0x2d, 0x8d, 0x23, 0x2c, 0xdc, 0xd3, 0x3c, 0xc2, 0xc3, 0xc5, 0xd2, 0x8c, 0x3d, 0x88, 0x3c, 0xc3, 0x2d, 0x83, 0xd8, 0xc0, 0xdd, 0xdc, 0x35, 0x3c, 0xcc, 0x22, 0x8c, 0x85, 0xc5, 0x8d, 0x32, 0xd2, 0x85, 0x30, 0x02, 0x52, 0xc8, 0x5c, 0x50, 0xc0, 0x83, 0x8c, 0x53, 0x3c, 0x82, 0xc2, 0xd3, 0xd8, 0xcc, 0x35, 0xc5, 0x3d, 0x5c, 0xcc, 0x5d, 0x3c, 0x23, 0x3d, 0x20, 0x33, 0x5c, 0x30, 0xc8, 0x53, 0xc8, 0xd5, 0x5c, 0x03, 0xdd, 0x58, 0x32, 0x38, 0x5c, 0xc2, 0xd2, 0x53, 0xd2, 0xcc, 0x23, 0x88, 0x83, 0xc0, 0xcc, 0xcd, 0x8c, 0xc5, 0xd2, 0x03, 0xcc, 0xcd, 0x5d, 0x0c, 0x2c, 0x0c }; + + private DESCryptoServiceProvider m_des = null; + private ICryptoTransform m_des_encryptor = null; + private ICryptoTransform m_des_decryptor = null; + private byte[] m_des_key = null; + + public byte[] Init(byte[] rsa_public_key = null) + { + if (rsa_public_key == null) + rsa_public_key = kPublicKey; + var pk = DecodePublicKey(rsa_public_key); + var key = GenDesKey(); + SetupDes(key); + var key_data = RsaEncrypt(pk, key); + int key_data_len = key_data.Length; + byte[] data = new byte[key_data_len + 2]; + data[0] = (byte)((key_data_len >> 8) & 0xff); + data[1] = (byte)(key_data_len & 0xff); + System.Array.Copy(key_data, 0, data, 2, key_data_len); + return data; + } + + public void SetupDes(byte[] key) + { + m_des_key = key; + m_des = CreateDES(); + m_des_encryptor = m_des.CreateEncryptor(); + m_des_decryptor = m_des.CreateDecryptor(); + } + + private DESCryptoServiceProvider CreateDES() + { + var m_des = new DESCryptoServiceProvider(); + m_des.Key = m_des_key; + m_des.IV = m_des_key; + m_des.Mode = CipherMode.ECB; + m_des.Padding = PaddingMode.None; + return m_des; + } + + static readonly byte[] kPandding = new byte[] { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; + + public static int CalcPanddingDataLen(int dataLen) + { + int mod = dataLen % 8; + return dataLen + (8 - mod); + } + + public int Encrypt(byte[] data, int dataOffset, int dataLen, byte[] outBuff, int outBuffOffset) + { + int mg = CalcPanddingDataLen(dataLen); + if (outBuff.Length - outBuffOffset < mg) + return -1; + if (m_des == null) + m_des = CreateDES(); + if (m_des_encryptor == null) + m_des_encryptor = m_des.CreateEncryptor(); + MemoryStream mem = new MemoryStream(outBuff); + mem.Position += outBuffOffset; + + CryptoStream st = new CryptoStream(mem, m_des_encryptor, CryptoStreamMode.Write); + //st.Clear(); + st.Write(data, dataOffset, dataLen); + if (mg > dataLen) + st.Write(kPandding, 0, mg - dataLen); + st.FlushFinalBlock(); + return (int)(mem.Position - outBuffOffset); + } + + byte[] m_outBuffer = new byte[1024]; + int m_outBuffer_Capacity = 1024; + //int m_outBuffer_Length = 0; + + private bool CheckOutBufferCapacity(int needCapacity) + { + if (needCapacity <= m_outBuffer_Capacity) + return true; + + m_outBuffer = new byte[needCapacity]; + m_outBuffer_Capacity = needCapacity; + + return true; + } + + public int EncryptProtoBeforeSend(SpStream inputStream, out byte[] outBuff) + { + int dataLen = inputStream.Length - 2; + int mg = CalcPanddingDataLen(dataLen); + + if (mg > dataLen) + inputStream.Write(kPandding, 0, mg - dataLen); + + //m_outBuffer_Length = 0; + CheckOutBufferCapacity(mg + 2); + if (m_des == null) + m_des = CreateDES(); + if (m_des_encryptor == null) + m_des_encryptor = m_des.CreateEncryptor(); + + int len = m_des_encryptor.TransformBlock(inputStream.Buffer, 2, mg, m_outBuffer, 2); + //Assert(count == mg); + m_outBuffer[0] = (byte)((len >> 8) & 0xff); + m_outBuffer[1] = (byte)(len & 0xff); + outBuff = m_outBuffer; + return len + 2; + } + + + public byte[] Decrypt(byte[] data, int offset, int len) + { + var d = m_des.CreateDecryptor(); + MemoryStream mem = new MemoryStream(); + CryptoStream st = new CryptoStream(mem, d, CryptoStreamMode.Write); + st.Write(data, offset, len); + st.FlushFinalBlock(); + return mem.ToArray(); + } + + + public SpStream DecryptAsSpStream(byte[] data, int offset, int len) + { + if (len % 8 != 0) + throw new System.ArgumentException("proto Encrypt : DecryptAsSpStream : len % 8 != 0 len=" + len); + if (data == null) + throw new System.ArgumentNullException("proto Encrypt : DecryptAsSpStream : data == null"); + if (m_des_decryptor == null) + m_des_decryptor = m_des.CreateDecryptor(); + byte[] buff = new byte[len]; + int dLen = m_des_decryptor.TransformBlock(data, offset, len, buff, 0); + dLen = CalcDataLen(buff, dLen); + return new SpStream(buff, 0, 0, dLen); + } + + private byte[] GenDesKey() + { + const int kDesKeyLength = 8; + byte[] key = new byte[kDesKeyLength]; + // 旧写法 + // Random.seed = (int)System.DateTime.Now.Ticks; + // 新写法 + Random.InitState((int)System.DateTime.Now.Ticks); + for (int i = 0; i < key.Length; i++) + { + key[i] = (byte)(Random.Range(0, 255)); + } + return key; + } + + private static byte[] RsaEncrypt(byte[] rsaKey, byte[] data) + { + RSACryptoServiceProvider rsa = RSADERParser.CreateEncoder(rsaKey); + return rsa.Encrypt(data, false); + } + + private static byte[] DecodePublicKey(byte[] data) + { + var des = new DESCryptoServiceProvider(); + var dk = new byte[] { (byte)'e', (byte)'9', (byte)'f', (byte)'e', (byte)'6', (byte)'a', (byte)'3', (byte)'2' }; + des.Key = dk; + des.Mode = CipherMode.ECB; + des.Padding = PaddingMode.None; + var e = des.CreateDecryptor(); + var decode_data = e.TransformFinalBlock(data, 0, data.Length); + int len = SCalcDataLen(decode_data); + if (len < decode_data.Length) + { + byte[] r = new byte[len]; + System.Array.Copy(decode_data, r, len); + return r; + } + return decode_data; + } + + public static int CalcDataLen(byte[] data) + { + if (data.Length < 8) + return -1; + int s = data.Length - 8; + if (s < 0) s = 0; + for (int i = data.Length - 1; i >= s; i--) + { + if (data[i] == 0x00) + continue; + if (data[i] == 0x80) + return i; + return -1; + } + return -1; + } + + public static int CalcDataLen(byte[] data, int dataLen) + { + if (dataLen < 8) + return -1; + int s = dataLen - 8; + if (s < 0) s = 0; + for (int i = dataLen - 1; i >= s; i--) + { + if (data[i] == 0x00) + continue; + if (data[i] == 0x80) + return i; + return -1; + } + return -1; + } + + public static int SCalcDataLen(byte[] data) + { + int len = CalcDataLen(data); + if (len == -1) return data.Length; + return len; + } +} + diff --git a/Assets/Editor/Utils/PlayerPrefsTools.cs.meta b/Assets/LuaFramework/Scripts/Network/ProtoEncrypt.cs.meta similarity index 83% rename from Assets/Editor/Utils/PlayerPrefsTools.cs.meta rename to Assets/LuaFramework/Scripts/Network/ProtoEncrypt.cs.meta index dfe7dbc..79ba241 100644 --- a/Assets/Editor/Utils/PlayerPrefsTools.cs.meta +++ b/Assets/LuaFramework/Scripts/Network/ProtoEncrypt.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: bf9845f3501f900418c8da6321898dcd +guid: 309c7374096ba91408212048fb92d43c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/LuaFramework/Scripts/Network/SocketClient.cs b/Assets/LuaFramework/Scripts/Network/SocketClient.cs index 24a0c95..fccd0d9 100644 --- a/Assets/LuaFramework/Scripts/Network/SocketClient.cs +++ b/Assets/LuaFramework/Scripts/Network/SocketClient.cs @@ -13,6 +13,8 @@ public enum DisType { } public class SocketClient { + public static bool loggedIn = false; + private TcpClient client = null; private NetworkStream outStream = null; private MemoryStream memStream; @@ -20,7 +22,6 @@ public class SocketClient { private const int MAX_READ = 8192; private byte[] byteBuffer = new byte[MAX_READ]; - public static bool loggedIn = false; // Use this for initialization public SocketClient() { @@ -48,21 +49,11 @@ public class SocketClient { /// void ConnectServer(string host, int port) { client = null; + client = new TcpClient(); + client.SendTimeout = 1000; + client.ReceiveTimeout = 1000; + client.NoDelay = true; try { - IPAddress[] address = Dns.GetHostAddresses(host); - if (address.Length == 0) { - Debug.LogError("host invalid"); - return; - } - if (address[0].AddressFamily == AddressFamily.InterNetworkV6) { - client = new TcpClient(AddressFamily.InterNetworkV6); - } - else { - client = new TcpClient(AddressFamily.InterNetwork); - } - client.SendTimeout = 1000; - client.ReceiveTimeout = 1000; - client.NoDelay = true; client.BeginConnect(host, port, new AsyncCallback(OnConnect), null); } catch (Exception e) { Close(); Debug.LogError(e.Message); @@ -75,7 +66,7 @@ public class SocketClient { void OnConnect(IAsyncResult asr) { outStream = client.GetStream(); client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null); - NetworkManager.AddEvent(Protocal.Connect, new ByteBuffer()); + //NetworkManager.AddEvent(Protocal.Connect, new ByteBuffer()); } /// @@ -91,7 +82,7 @@ public class SocketClient { writer.Write(message); writer.Flush(); if (client != null && client.Connected) { - //NetworkStream stream = client.GetStream(); + //NetworkStream stream = client.GetStream(); byte[] payload = ms.ToArray(); outStream.BeginWrite(payload, 0, payload.Length, new AsyncCallback(OnWrite), null); } else { @@ -119,7 +110,6 @@ public class SocketClient { client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null); } } catch (Exception ex) { - //PrintBytes(); OnDisconnected(DisType.Exception, ex.Message); } } @@ -127,14 +117,15 @@ public class SocketClient { /// /// 丢失链接 /// - void OnDisconnected(DisType dis, string msg) { + void OnDisconnected(DisType dis, string msg) + { Close(); //关掉客户端链接 int protocal = dis == DisType.Exception ? Protocal.Exception : Protocal.Disconnect; ByteBuffer buffer = new ByteBuffer(); buffer.WriteShort((ushort)protocal); - NetworkManager.AddEvent(protocal, buffer); + //NetworkManager.AddEvent(protocal, buffer); Debug.LogError("Connection was closed by the server:>" + msg + " Distype:>" + dis); } @@ -200,14 +191,15 @@ public class SocketClient { /// 接收到消息 /// /// - void OnReceivedMessage(MemoryStream ms) { + void OnReceivedMessage(MemoryStream ms) + { BinaryReader r = new BinaryReader(ms); byte[] message = r.ReadBytes((int)(ms.Length - ms.Position)); //int msglen = message.Length; ByteBuffer buffer = new ByteBuffer(message); - int mainId = buffer.ReadShort(); - NetworkManager.AddEvent(mainId, buffer); + /*int mainId = */buffer.ReadShort(); + //NetworkManager.AddEvent(mainId, buffer); } diff --git a/Assets/LuaFramework/Scripts/Network/SocketClient.cs.meta b/Assets/LuaFramework/Scripts/Network/SocketClient.cs.meta index 8171171..73d6685 100644 --- a/Assets/LuaFramework/Scripts/Network/SocketClient.cs.meta +++ b/Assets/LuaFramework/Scripts/Network/SocketClient.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 2c8a96e463bf5d74ca866ab1a04f00d2 -timeCreated: 1440243780 -licenseType: Pro +guid: 8bbfb5388b5ef0144a29dd66da9fcc5c MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Assets/LuaFramework/Scripts/Utility/LuaHelper.cs b/Assets/LuaFramework/Scripts/Utility/LuaHelper.cs index 4fe7118..7c21c3c 100644 --- a/Assets/LuaFramework/Scripts/Utility/LuaHelper.cs +++ b/Assets/LuaFramework/Scripts/Utility/LuaHelper.cs @@ -12,8 +12,9 @@ namespace LuaFramework { /// /// /// - public static System.Type GetType(string classname) { - Assembly assb = Assembly.GetExecutingAssembly(); //.GetExecutingAssembly(); + public static System.Type GetType(string classname) + { + Assembly assb = Assembly.GetExecutingAssembly(); System.Type t = null; t = assb.GetType(classname); ; if (t == null) { @@ -26,33 +27,7 @@ namespace LuaFramework { /// 网络管理器 /// public static NetworkManager GetNetManager() { - return AppFacade.Instance.GetManager(ManagerName.Network); - } - - /// - /// Lua管理器 - /// - public static LuaManager GetLuaManager() { - return AppFacade.Instance.GetManager(ManagerName.Lua); - } - - /// - /// pbc/pblua函数回调 - /// - /// - public static void OnCallLuaFunc(LuaByteBuffer data, LuaFunction func) { - if (func != null) func.Call(data); - Debug.LogWarning("OnCallLuaFunc length:>>" + data.buffer.Length); - } - - /// - /// cjson函数回调 - /// - /// - /// - public static void OnJsonCallFunc(string data, LuaFunction func) { - Debug.LogWarning("OnJsonCallback data:>>" + data + " lenght:>>" + data.Length); - if (func != null) func.Call(data); + return NetworkManager.GetInstance(); } } } \ No newline at end of file diff --git a/Assets/LuaFramework/Scripts/Utility/Util.cs b/Assets/LuaFramework/Scripts/Utility/Util.cs index 18a031a..c4f96e6 100644 --- a/Assets/LuaFramework/Scripts/Utility/Util.cs +++ b/Assets/LuaFramework/Scripts/Utility/Util.cs @@ -1,109 +1,72 @@ -using UnityEngine; +#define DO_NOT_CHECK_ENVI +using UnityEngine; using System; using System.IO; using System.Text; -using System.Collections; -using System.Collections.Generic; using System.Security.Cryptography; -using System.Text.RegularExpressions; +using System.Reflection; using LuaInterface; -using LuaFramework; +using System.Xml; -namespace LuaFramework { - public class Util { - private static List luaPaths = new List(); +#if UNITY_EDITOR +using UnityEditor; +#endif - public static int Int(object o) { +namespace LuaFramework +{ + public class Util + { + public static int Int(object o) + { return Convert.ToInt32(o); } - public static float Float(object o) { + public static float Float(object o) + { return (float)Math.Round(Convert.ToSingle(o), 2); } - public static long Long(object o) { + public static long Long(object o) + { return Convert.ToInt64(o); } - public static int Random(int min, int max) { + public static int Random(int min, int max) + { return UnityEngine.Random.Range(min, max); } - public static float Random(float min, float max) { + public static float Random(float min, float max) + { return UnityEngine.Random.Range(min, max); } - public static string Uid(string uid) { + public static string Uid(string uid) + { int position = uid.LastIndexOf('_'); return uid.Remove(0, position + 1); } - public static long GetTime() { + public static long GetTime() + { TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1, 0, 0, 0).Ticks); return (long)ts.TotalMilliseconds; } - /// - /// 搜索子物体组件-GameObject版 - /// - public static T Get(GameObject go, string subnode) where T : Component { - if (go != null) { - Transform sub = go.transform.Find(subnode); - if (sub != null) return sub.GetComponent(); - } - return null; - } - - /// - /// 搜索子物体组件-Transform版 - /// - public static T Get(Transform go, string subnode) where T : Component { - if (go != null) { - Transform sub = go.Find(subnode); - if (sub != null) return sub.GetComponent(); - } - return null; - } - - /// - /// 搜索子物体组件-Component版 - /// - public static T Get(Component go, string subnode) where T : Component { - return go.transform.Find(subnode).GetComponent(); - } - - /// - /// 添加组件 - /// - public static T Add(GameObject go) where T : Component { - if (go != null) { - T[] ts = go.GetComponents(); - for (int i = 0; i < ts.Length; i++) { - if (ts[i] != null) GameObject.Destroy(ts[i]); - } - return go.gameObject.AddComponent(); - } - return null; - } - - /// - /// 添加组件 - /// - public static T Add(Transform go) where T : Component { - return Add(go.gameObject); - } /// /// 查找子对象 /// - public static GameObject Child(GameObject go, string subnode) { + public static GameObject Child(GameObject go, string subnode) + { return Child(go.transform, subnode); } /// /// 查找子对象 /// - public static GameObject Child(Transform go, string subnode) { + public static GameObject Child(Transform go, string subnode) + { Transform tran = go.Find(subnode); if (tran == null) return null; return tran.gameObject; @@ -112,14 +75,16 @@ namespace LuaFramework { /// /// 取平级对象 /// - public static GameObject Peer(GameObject go, string subnode) { + public static GameObject Peer(GameObject go, string subnode) + { return Peer(go.transform, subnode); } /// /// 取平级对象 /// - public static GameObject Peer(Transform go, string subnode) { + public static GameObject Peer(Transform go, string subnode) + { Transform tran = go.parent.Find(subnode); if (tran == null) return null; return tran.gameObject; @@ -128,14 +93,16 @@ namespace LuaFramework { /// /// 计算字符串的MD5值 /// - public static string md5(string source) { + public static string md5(string source) + { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] data = System.Text.Encoding.UTF8.GetBytes(source); byte[] md5Data = md5.ComputeHash(data, 0, data.Length); md5.Clear(); string destString = ""; - for (int i = 0; i < md5Data.Length; i++) { + for (int i = 0; i < md5Data.Length; i++) + { destString += System.Convert.ToString(md5Data[i], 16).PadLeft(2, '0'); } destString = destString.PadLeft(32, '0'); @@ -145,19 +112,24 @@ namespace LuaFramework { /// /// 计算文件的MD5值 /// - public static string md5file(string file) { - try { + public static string md5file(string file) + { + try + { FileStream fs = new FileStream(file, FileMode.Open); System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(fs); fs.Close(); StringBuilder sb = new StringBuilder(); - for (int i = 0; i < retVal.Length; i++) { + for (int i = 0; i < retVal.Length; i++) + { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); - } catch (Exception ex) { + } + catch (Exception ex) + { throw new Exception("md5file() fail, error:" + ex.Message); } } @@ -165,9 +137,11 @@ namespace LuaFramework { /// /// 清除所有子节点 /// - public static void ClearChild(Transform go) { + public static void ClearChild(Transform go) + { if (go == null) return; - for (int i = go.childCount - 1; i >= 0; i--) { + for (int i = go.childCount - 1; i >= 0; i--) + { GameObject.Destroy(go.GetChild(i).gameObject); } } @@ -175,89 +149,158 @@ namespace LuaFramework { /// /// 清理内存 /// - public static void ClearMemory() { + public static void ClearMemory() + { GC.Collect(); Resources.UnloadUnusedAssets(); - LuaManager mgr = AppFacade.Instance.GetManager(ManagerName.Lua); - if (mgr != null) mgr.LuaGC(); - } - - /// - /// 取得行文本 - /// - public static string GetFileText(string path) { - return File.ReadAllText(path); + LuaManager.instance.LuaGC(); } /// - /// 网络可用 + /// 取得数据存放目录 /// - public static bool NetAvailable { - get { - return Application.internetReachability != NetworkReachability.NotReachable; - } - } - - /// - /// 是否是无线 - /// - public static bool IsWifi { - get { - return Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork; + public static string DataPath + { + get + { + string game = AppConst.AppName.ToLower(); + if (Application.isMobilePlatform) + { + return Application.persistentDataPath + "/" + game + "/"; + } + if (Application.platform == RuntimePlatform.WindowsPlayer) + { + return Application.streamingAssetsPath + "/"; + } + if (AppConst.DebugMode && Application.isEditor) + { + return Application.streamingAssetsPath + "/"; + } + if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor) + { + //int i = Application.dataPath.LastIndexOf('/'); + //return Application.dataPath.Substring(0, i + 1) + game + "/"; + //return Application.dataPath + "/" + game + "/"; + return Application.streamingAssetsPath + "/"; + } + return "c:/" + game + "/"; } } /// /// 应用程序内容路径 /// - public static string AppContentPath() { + public static string AppContentPath() + { string path = string.Empty; - switch (Application.platform) { + switch (Application.platform) + { case RuntimePlatform.Android: path = "jar:file://" + Application.dataPath + "!/assets/"; - break; + break; case RuntimePlatform.IPhonePlayer: path = Application.dataPath + "/Raw/"; - break; + break; default: - path = Application.dataPath + "/" + AppConst.AssetDir + "/"; - break; + path = Application.dataPath + "/StreamingAssets/"; + break; } return path; } - public static void Log(string str) { - Debug.Log(str); + + public static void Log(string str) + { + GameLogger.Log(str); + } + + public static void LogGreen(string str) + { + GameLogger.LogGreen(str); + } + + public static void LogYellow(string str) + { + GameLogger.LogYellow(str); + } + + public static void LogWarning(string str) + { + GameLogger.LogWarning(str); + } + + public static void LogError(string str) + { + GameLogger.LogError(str); + } + + public static Component AddComponent(GameObject go, string assembly, string classname) + { + Assembly asmb = Assembly.Load(assembly); + Type t = asmb.GetType(assembly + "." + classname); + return go.AddComponent(t); + } + + public static LuaFunction GetFunction(string module, string func, bool beLogMiss = true) + { + return LuaManager.instance.GetFunction(module + "." + func, beLogMiss); + } + + /// + /// 载入Prefab + /// + /// + public static GameObject LoadPrefab(string name) + { + return Resources.Load(name, typeof(GameObject)) as GameObject; } - public static void LogWarning(string str) { - Debug.LogWarning(str); + /// + /// 执行Lua方法 + /// + public static object[] CallMethod(string module, string func, params object[] args) + { + return LuaManager.instance.CallFunction(module + "." + func, args); } - public static void LogError(string str) { - Debug.LogError(str); + /// + /// 根据path读取文件 + /// + /// + /// + public static string ReadFileFromPath(string fileName) + { + return LuaFileUtils.Instance.ReadOtherFile(fileName); } /// /// 防止初学者不按步骤来操作 /// /// - public static int CheckRuntimeFile() { + static int CheckRuntimeFile() + { if (!Application.isEditor) return 0; string streamDir = Application.dataPath + "/StreamingAssets/"; - if (!Directory.Exists(streamDir)) { + if (!Directory.Exists(streamDir)) + { return -1; - } else { + } + else + { string[] files = Directory.GetFiles(streamDir); if (files.Length == 0) return -1; - if (!File.Exists(streamDir + "files.txt")) { + if (!File.Exists(streamDir + "files.txt")) + { return -1; } } string sourceDir = AppConst.FrameworkRoot + "/ToLua/Source/Generate/"; - if (!Directory.Exists(sourceDir)) { + if (!Directory.Exists(sourceDir)) + { return -2; - } else { + } + else + { string[] files = Directory.GetFiles(sourceDir); if (files.Length == 0) return -2; } @@ -265,26 +308,91 @@ namespace LuaFramework { } /// - /// 执行Lua方法 + /// 检查运行环境 /// - public static object[] CallMethod(string module, string func, params object[] args) { - LuaManager luaMgr = AppFacade.Instance.GetManager(ManagerName.Lua); - if (luaMgr == null) return null; - return luaMgr.CallFunction(module + "." + func, args); + public static bool CheckEnvironment() + { +#if DO_NOT_CHECK_ENVI + return true; +#else +#if UNITY_EDITOR + int resultId = Util.CheckRuntimeFile(); + if (resultId == -1) { + GameLogger.LogError("没有找到框架所需要的资源,单击Game菜单下Build xxx Resource生成!!"); + EditorApplication.isPlaying = false; + return false; + } else if (resultId == -2) { + GameLogger.LogError("没有找到Wrap脚本缓存,单击Lua菜单下Gen Lua Wrap Files生成脚本!!"); + EditorApplication.isPlaying = false; + return false; + } + if (Application.loadedLevelName == "Test" && !AppConst.GameLoggerMode) { + GameLogger.LogError("测试场景,必须打开调试模式,AppConst.GameLoggerMode = true!!"); + EditorApplication.isPlaying = false; + return false; + } +#endif + return true; +#endif // DO_NOT_CHECK_ENVI } - public static void RecordStartTime(string key) + //Lua 里面读取配置表文件 + public static LuaTable ReadXMLConfigFile(string fileName) { - var ts = System.DateTime.Now - System.DateTime.Parse("1970-1-1"); - PlayerPrefs.SetString(key, ts.TotalSeconds.ToString()); + XmlDocument doc = XMLUtil.GetEssentialXmlCfg(fileName); + if (doc == null) + { + GameLogger.LogError("ReadXMLConfigFile doc is nil ... " + fileName); + return null; + } + + return ReadXMLDoc(doc); } - public static void EndRecordTime(string key) + public static LuaTable ReadXMLDoc(XmlDocument doc) { - var ts = System.DateTime.Now - System.DateTime.Parse("1970-1-1"); - var nowT = ts.TotalSeconds; - var startT = double.Parse(PlayerPrefs.GetString(key, "0")); - GameLogger.Log(key + "耗时: " + (nowT - startT) + "秒"); + LuaTable tab = LuaManager.instance.CreateLuaTable(); + + if (tab == null) + { + GameLogger.LogError("Util ReadXMLDoc create lua table failed...."); + return null; + } + + XmlNodeList nodeList = doc.GetElementsByTagName("item"); + for (int i = 0, count = nodeList.Count; i < count; i++) + { + + XmlNode node = nodeList[i]; + int col = 0; + LuaTable colTab = null; + foreach (XmlNode attrNode in node.Attributes) + { + string fieldName = attrNode.Name; + string fieldValueStr = attrNode.Value; + + //默认第一列作为key + if (col == 0) + { + //用列号为key + string keyStr = (i + 1).ToString(); + tab.AddTable(keyStr); + colTab = tab[keyStr] as LuaTable; + } + + if (colTab != null) + { + colTab[fieldName] = fieldValueStr; + } + + col++; + + } + + } + + return tab; } + } -} \ No newline at end of file +} diff --git a/Assets/LuaFramework/Scripts/Utility/WrapCSObj.cs b/Assets/LuaFramework/Scripts/Utility/WrapCSObj.cs new file mode 100644 index 0000000..8a89767 --- /dev/null +++ b/Assets/LuaFramework/Scripts/Utility/WrapCSObj.cs @@ -0,0 +1,70 @@ +using LuaInterface; + +namespace LuaFramework +{ + class WrapCSObj + { + public object obj; + System.Type type; + + public WrapCSObj(object obj) + { + this.obj = obj; + type = obj.GetType(); + } + + public static void Register(LuaState L) + { + L.BeginClass(typeof(WrapCSObj), typeof(System.Object)); + L.RegFunction("__index", Index); + L.RegFunction("__call", CreateNew); + L.EndClass(); + } + + [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] + public static int Index(System.IntPtr L) + { + try + { + ToLua.CheckArgsCount(L, 2); + var wrap = (WrapCSObj)ToLua.CheckObject(L, 1, typeof(WrapCSObj)); + string name = ToLua.ToString(L, 2); + var val = wrap.GetVarByName(name); + ToLua.Push(L, val); + return 1; + } + catch (System.Exception e) + { + return LuaDLL.toluaL_exception(L, e); + } + } + + [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] + public static int CreateNew(System.IntPtr L) + { + try + { + ToLua.CheckArgsCount(L, 2); + var obj = ToLua.ToObject(L, 2); + var wrap = new WrapCSObj(obj); + ToLua.Push(L, wrap); + return 1; + } + catch (System.Exception e) + { + return LuaDLL.toluaL_exception(L, e); + } + } + + public object GetVarByName(string name) + { + var pi = type.GetProperty(name); + if (pi != null) + return pi.GetValue(obj, null); + var fi = type.GetField(name); + if (fi != null) + return fi.GetValue(obj); + return null; + } + } +} \ No newline at end of file diff --git a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_LightWrap.cs.meta b/Assets/LuaFramework/Scripts/Utility/WrapCSObj.cs.meta similarity index 83% rename from Assets/LuaFramework/ToLua/BaseType/UnityEngine_LightWrap.cs.meta rename to Assets/LuaFramework/Scripts/Utility/WrapCSObj.cs.meta index b903a9c..15d9d9d 100644 --- a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_LightWrap.cs.meta +++ b/Assets/LuaFramework/Scripts/Utility/WrapCSObj.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fd172be26223a894daf7136d3b6207b4 +guid: 26a7730c910012e4290db5d0231988d9 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/LuaFramework/Scripts/View/AppView.cs b/Assets/LuaFramework/Scripts/View/AppView.cs deleted file mode 100644 index 1deda9c..0000000 --- a/Assets/LuaFramework/Scripts/View/AppView.cs +++ /dev/null @@ -1,76 +0,0 @@ -using UnityEngine; -using LuaFramework; -using System.Collections.Generic; - -public class AppView : View { - private string message; - - /// - /// 监听的消息 - /// - List MessageList { - get { - return new List() - { - NotiConst.UPDATE_MESSAGE, - NotiConst.UPDATE_EXTRACT, - NotiConst.UPDATE_DOWNLOAD, - NotiConst.UPDATE_PROGRESS, - }; - } - } - - void Awake() { - RemoveMessage(this, MessageList); - RegisterMessage(this, MessageList); - } - - /// - /// 处理View消息 - /// - /// - public override void OnMessage(IMessage message) { - string name = message.Name; - object body = message.Body; - switch (name) { - case NotiConst.UPDATE_MESSAGE: //更新消息 - UpdateMessage(body.ToString()); - break; - case NotiConst.UPDATE_EXTRACT: //更新解压 - UpdateExtract(body.ToString()); - break; - case NotiConst.UPDATE_DOWNLOAD: //更新下载 - UpdateDownload(body.ToString()); - break; - case NotiConst.UPDATE_PROGRESS: //更新下载进度 - UpdateProgress(body.ToString()); - break; - } - } - - public void UpdateMessage(string data) { - this.message = data; - } - - public void UpdateExtract(string data) { - this.message = data; - } - - public void UpdateDownload(string data) { - this.message = data; - } - - public void UpdateProgress(string data) { - this.message = data; - } - - void OnGUI() { - GUI.Label(new Rect(10, 120, 960, 50), message); - - GUI.Label(new Rect(10, 0, 500, 50), "(1) 单击 \"Lua/Gen Lua Wrap Files\"。"); - GUI.Label(new Rect(10, 20, 500, 50), "(2) 运行Unity游戏"); - GUI.Label(new Rect(10, 40, 500, 50), "PS: 清除缓存,单击\"Lua/Clear LuaBinder File + Wrap Files\"。"); - GUI.Label(new Rect(10, 60, 900, 50), "PS: 若运行到真机,请设置Const.DebugMode=false,本地调试请设置Const.DebugMode=true"); - GUI.Label(new Rect(10, 80, 500, 50), "PS: 加Unity+ulua技术讨论群:>>341746602"); - } -} diff --git a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_LightWrap.cs b/Assets/LuaFramework/ToLua/BaseType/UnityEngine_LightWrap.cs deleted file mode 100644 index d205761..0000000 --- a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_LightWrap.cs +++ /dev/null @@ -1,1487 +0,0 @@ -//this source code was auto-generated by tolua#, do not modify it -using System; -using LuaInterface; - -public class UnityEngine_LightWrap -{ - public static void Register(LuaState L) - { - L.BeginClass(typeof(UnityEngine.Light), typeof(UnityEngine.Behaviour)); - L.RegFunction("Reset", Reset); - // L.RegFunction("SetLightDirty", SetLightDirty); - L.RegFunction("AddCommandBuffer", AddCommandBuffer); - L.RegFunction("AddCommandBufferAsync", AddCommandBufferAsync); - L.RegFunction("RemoveCommandBuffer", RemoveCommandBuffer); - L.RegFunction("RemoveCommandBuffers", RemoveCommandBuffers); - L.RegFunction("RemoveAllCommandBuffers", RemoveAllCommandBuffers); - L.RegFunction("GetCommandBuffers", GetCommandBuffers); - L.RegFunction("GetLights", GetLights); - L.RegFunction("New", _CreateUnityEngine_Light); - L.RegFunction("__eq", op_Equality); - L.RegFunction("__tostring", ToLua.op_ToString); - L.RegVar("type", get_type, set_type); - L.RegVar("shape", get_shape, set_shape); - L.RegVar("spotAngle", get_spotAngle, set_spotAngle); - L.RegVar("innerSpotAngle", get_innerSpotAngle, set_innerSpotAngle); - L.RegVar("color", get_color, set_color); - L.RegVar("colorTemperature", get_colorTemperature, set_colorTemperature); - L.RegVar("useColorTemperature", get_useColorTemperature, set_useColorTemperature); - L.RegVar("intensity", get_intensity, set_intensity); - L.RegVar("bounceIntensity", get_bounceIntensity, set_bounceIntensity); - L.RegVar("useBoundingSphereOverride", get_useBoundingSphereOverride, set_useBoundingSphereOverride); - L.RegVar("boundingSphereOverride", get_boundingSphereOverride, set_boundingSphereOverride); - L.RegVar("useViewFrustumForShadowCasterCull", get_useViewFrustumForShadowCasterCull, set_useViewFrustumForShadowCasterCull); - L.RegVar("shadowCustomResolution", get_shadowCustomResolution, set_shadowCustomResolution); - L.RegVar("shadowBias", get_shadowBias, set_shadowBias); - L.RegVar("shadowNormalBias", get_shadowNormalBias, set_shadowNormalBias); - L.RegVar("shadowNearPlane", get_shadowNearPlane, set_shadowNearPlane); - L.RegVar("useShadowMatrixOverride", get_useShadowMatrixOverride, set_useShadowMatrixOverride); - L.RegVar("shadowMatrixOverride", get_shadowMatrixOverride, set_shadowMatrixOverride); - L.RegVar("range", get_range, set_range); - L.RegVar("flare", get_flare, set_flare); - L.RegVar("bakingOutput", get_bakingOutput, set_bakingOutput); - L.RegVar("cullingMask", get_cullingMask, set_cullingMask); - L.RegVar("renderingLayerMask", get_renderingLayerMask, set_renderingLayerMask); - L.RegVar("lightShadowCasterMode", get_lightShadowCasterMode, set_lightShadowCasterMode); - L.RegVar("shadows", get_shadows, set_shadows); - L.RegVar("shadowStrength", get_shadowStrength, set_shadowStrength); - L.RegVar("shadowResolution", get_shadowResolution, set_shadowResolution); - L.RegVar("layerShadowCullDistances", get_layerShadowCullDistances, set_layerShadowCullDistances); - L.RegVar("cookieSize", get_cookieSize, set_cookieSize); - L.RegVar("cookie", get_cookie, set_cookie); - L.RegVar("renderMode", get_renderMode, set_renderMode); - L.RegVar("commandBufferCount", get_commandBufferCount, null); - L.EndClass(); - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int _CreateUnityEngine_Light(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 0) - { - UnityEngine.Light obj = new UnityEngine.Light(); - ToLua.PushSealed(L, obj); - return 1; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: UnityEngine.Light.New"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int Reset(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - obj.Reset(); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - // [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - // static int SetLightDirty(IntPtr L) - // { - // try - // { - // ToLua.CheckArgsCount(L, 1); - // UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - // obj.SetLightDirty(); - // return 0; - // } - // catch (Exception e) - // { - // return LuaDLL.toluaL_exception(L, e); - // } - // } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int AddCommandBuffer(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 3) - { - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - UnityEngine.Rendering.LightEvent arg0 = (UnityEngine.Rendering.LightEvent)ToLua.CheckObject(L, 2, typeof(UnityEngine.Rendering.LightEvent)); - UnityEngine.Rendering.CommandBuffer arg1 = (UnityEngine.Rendering.CommandBuffer)ToLua.CheckObject(L, 3); - obj.AddCommandBuffer(arg0, arg1); - return 0; - } - else if (count == 4) - { - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - UnityEngine.Rendering.LightEvent arg0 = (UnityEngine.Rendering.LightEvent)ToLua.CheckObject(L, 2, typeof(UnityEngine.Rendering.LightEvent)); - UnityEngine.Rendering.CommandBuffer arg1 = (UnityEngine.Rendering.CommandBuffer)ToLua.CheckObject(L, 3); - UnityEngine.Rendering.ShadowMapPass arg2 = (UnityEngine.Rendering.ShadowMapPass)ToLua.CheckObject(L, 4, typeof(UnityEngine.Rendering.ShadowMapPass)); - obj.AddCommandBuffer(arg0, arg1, arg2); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.Light.AddCommandBuffer"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int AddCommandBufferAsync(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 4) - { - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - UnityEngine.Rendering.LightEvent arg0 = (UnityEngine.Rendering.LightEvent)ToLua.CheckObject(L, 2, typeof(UnityEngine.Rendering.LightEvent)); - UnityEngine.Rendering.CommandBuffer arg1 = (UnityEngine.Rendering.CommandBuffer)ToLua.CheckObject(L, 3); - UnityEngine.Rendering.ComputeQueueType arg2 = (UnityEngine.Rendering.ComputeQueueType)ToLua.CheckObject(L, 4, typeof(UnityEngine.Rendering.ComputeQueueType)); - obj.AddCommandBufferAsync(arg0, arg1, arg2); - return 0; - } - else if (count == 5) - { - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - UnityEngine.Rendering.LightEvent arg0 = (UnityEngine.Rendering.LightEvent)ToLua.CheckObject(L, 2, typeof(UnityEngine.Rendering.LightEvent)); - UnityEngine.Rendering.CommandBuffer arg1 = (UnityEngine.Rendering.CommandBuffer)ToLua.CheckObject(L, 3); - UnityEngine.Rendering.ShadowMapPass arg2 = (UnityEngine.Rendering.ShadowMapPass)ToLua.CheckObject(L, 4, typeof(UnityEngine.Rendering.ShadowMapPass)); - UnityEngine.Rendering.ComputeQueueType arg3 = (UnityEngine.Rendering.ComputeQueueType)ToLua.CheckObject(L, 5, typeof(UnityEngine.Rendering.ComputeQueueType)); - obj.AddCommandBufferAsync(arg0, arg1, arg2, arg3); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.Light.AddCommandBufferAsync"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int RemoveCommandBuffer(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 3); - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - UnityEngine.Rendering.LightEvent arg0 = (UnityEngine.Rendering.LightEvent)ToLua.CheckObject(L, 2, typeof(UnityEngine.Rendering.LightEvent)); - UnityEngine.Rendering.CommandBuffer arg1 = (UnityEngine.Rendering.CommandBuffer)ToLua.CheckObject(L, 3); - obj.RemoveCommandBuffer(arg0, arg1); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int RemoveCommandBuffers(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - UnityEngine.Rendering.LightEvent arg0 = (UnityEngine.Rendering.LightEvent)ToLua.CheckObject(L, 2, typeof(UnityEngine.Rendering.LightEvent)); - obj.RemoveCommandBuffers(arg0); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int RemoveAllCommandBuffers(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - obj.RemoveAllCommandBuffers(); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int GetCommandBuffers(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.Light obj = (UnityEngine.Light)ToLua.CheckObject(L, 1, typeof(UnityEngine.Light)); - UnityEngine.Rendering.LightEvent arg0 = (UnityEngine.Rendering.LightEvent)ToLua.CheckObject(L, 2, typeof(UnityEngine.Rendering.LightEvent)); - UnityEngine.Rendering.CommandBuffer[] o = obj.GetCommandBuffers(arg0); - ToLua.Push(L, o); - return 1; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int GetLights(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.LightType arg0 = (UnityEngine.LightType)ToLua.CheckObject(L, 1, typeof(UnityEngine.LightType)); - int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); - UnityEngine.Light[] o = UnityEngine.Light.GetLights(arg0, arg1); - ToLua.Push(L, o); - return 1; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int op_Equality(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.ToObject(L, 1); - UnityEngine.Object arg1 = (UnityEngine.Object)ToLua.ToObject(L, 2); - bool o = arg0 == arg1; - LuaDLL.lua_pushboolean(L, o); - return 1; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_type(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightType ret = obj.type; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index type on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shape(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightShape ret = obj.shape; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shape on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_spotAngle(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.spotAngle; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index spotAngle on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_innerSpotAngle(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.innerSpotAngle; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index innerSpotAngle on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_color(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Color ret = obj.color; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index color on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_colorTemperature(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.colorTemperature; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index colorTemperature on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_useColorTemperature(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - bool ret = obj.useColorTemperature; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useColorTemperature on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_intensity(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.intensity; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index intensity on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_bounceIntensity(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.bounceIntensity; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index bounceIntensity on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_useBoundingSphereOverride(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - bool ret = obj.useBoundingSphereOverride; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useBoundingSphereOverride on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_boundingSphereOverride(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Vector4 ret = obj.boundingSphereOverride; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index boundingSphereOverride on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_useViewFrustumForShadowCasterCull(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - bool ret = obj.useViewFrustumForShadowCasterCull; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useViewFrustumForShadowCasterCull on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shadowCustomResolution(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - int ret = obj.shadowCustomResolution; - LuaDLL.lua_pushinteger(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowCustomResolution on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shadowBias(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.shadowBias; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowBias on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shadowNormalBias(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.shadowNormalBias; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowNormalBias on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shadowNearPlane(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.shadowNearPlane; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowNearPlane on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_useShadowMatrixOverride(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - bool ret = obj.useShadowMatrixOverride; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useShadowMatrixOverride on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shadowMatrixOverride(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Matrix4x4 ret = obj.shadowMatrixOverride; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowMatrixOverride on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_range(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.range; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index range on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_flare(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Flare ret = obj.flare; - ToLua.PushSealed(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index flare on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_bakingOutput(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightBakingOutput ret = obj.bakingOutput; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index bakingOutput on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_cullingMask(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - int ret = obj.cullingMask; - LuaDLL.lua_pushinteger(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index cullingMask on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_renderingLayerMask(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - int ret = obj.renderingLayerMask; - LuaDLL.lua_pushinteger(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index renderingLayerMask on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_lightShadowCasterMode(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightShadowCasterMode ret = obj.lightShadowCasterMode; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index lightShadowCasterMode on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shadows(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightShadows ret = obj.shadows; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadows on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shadowStrength(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.shadowStrength; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowStrength on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shadowResolution(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Rendering.LightShadowResolution ret = obj.shadowResolution; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowResolution on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_layerShadowCullDistances(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float[] ret = obj.layerShadowCullDistances; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index layerShadowCullDistances on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_cookieSize(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float ret = obj.cookieSize; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index cookieSize on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_cookie(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Texture ret = obj.cookie; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index cookie on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_renderMode(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightRenderMode ret = obj.renderMode; - ToLua.Push(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index renderMode on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_commandBufferCount(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - int ret = obj.commandBufferCount; - LuaDLL.lua_pushinteger(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index commandBufferCount on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_type(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightType arg0 = (UnityEngine.LightType)ToLua.CheckObject(L, 2, typeof(UnityEngine.LightType)); - obj.type = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index type on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shape(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightShape arg0 = (UnityEngine.LightShape)ToLua.CheckObject(L, 2, typeof(UnityEngine.LightShape)); - obj.shape = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shape on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_spotAngle(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.spotAngle = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index spotAngle on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_innerSpotAngle(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.innerSpotAngle = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index innerSpotAngle on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_color(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Color arg0 = ToLua.ToColor(L, 2); - obj.color = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index color on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_colorTemperature(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.colorTemperature = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index colorTemperature on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_useColorTemperature(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.useColorTemperature = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useColorTemperature on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_intensity(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.intensity = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index intensity on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_bounceIntensity(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.bounceIntensity = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index bounceIntensity on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_useBoundingSphereOverride(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.useBoundingSphereOverride = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useBoundingSphereOverride on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_boundingSphereOverride(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Vector4 arg0 = ToLua.ToVector4(L, 2); - obj.boundingSphereOverride = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index boundingSphereOverride on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_useViewFrustumForShadowCasterCull(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.useViewFrustumForShadowCasterCull = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useViewFrustumForShadowCasterCull on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shadowCustomResolution(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); - obj.shadowCustomResolution = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowCustomResolution on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shadowBias(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.shadowBias = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowBias on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shadowNormalBias(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.shadowNormalBias = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowNormalBias on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shadowNearPlane(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.shadowNearPlane = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowNearPlane on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_useShadowMatrixOverride(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.useShadowMatrixOverride = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useShadowMatrixOverride on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shadowMatrixOverride(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Matrix4x4 arg0 = StackTraits.Check(L, 2); - obj.shadowMatrixOverride = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowMatrixOverride on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_range(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.range = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index range on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_flare(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Flare arg0 = (UnityEngine.Flare)ToLua.CheckObject(L, 2, typeof(UnityEngine.Flare)); - obj.flare = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index flare on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_bakingOutput(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightBakingOutput arg0 = StackTraits.Check(L, 2); - obj.bakingOutput = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index bakingOutput on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_cullingMask(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); - obj.cullingMask = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index cullingMask on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_renderingLayerMask(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); - obj.renderingLayerMask = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index renderingLayerMask on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_lightShadowCasterMode(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightShadowCasterMode arg0 = (UnityEngine.LightShadowCasterMode)ToLua.CheckObject(L, 2, typeof(UnityEngine.LightShadowCasterMode)); - obj.lightShadowCasterMode = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index lightShadowCasterMode on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shadows(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightShadows arg0 = (UnityEngine.LightShadows)ToLua.CheckObject(L, 2, typeof(UnityEngine.LightShadows)); - obj.shadows = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadows on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shadowStrength(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.shadowStrength = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowStrength on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_shadowResolution(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Rendering.LightShadowResolution arg0 = (UnityEngine.Rendering.LightShadowResolution)ToLua.CheckObject(L, 2, typeof(UnityEngine.Rendering.LightShadowResolution)); - obj.shadowResolution = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shadowResolution on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_layerShadowCullDistances(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float[] arg0 = ToLua.CheckNumberArray(L, 2); - obj.layerShadowCullDistances = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index layerShadowCullDistances on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_cookieSize(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.cookieSize = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index cookieSize on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_cookie(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.Texture arg0 = (UnityEngine.Texture)ToLua.CheckObject(L, 2); - obj.cookie = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index cookie on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_renderMode(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.Light obj = (UnityEngine.Light)o; - UnityEngine.LightRenderMode arg0 = (UnityEngine.LightRenderMode)ToLua.CheckObject(L, 2, typeof(UnityEngine.LightRenderMode)); - obj.renderMode = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index renderMode on a nil value"); - } - } -} - diff --git a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_MeshRendererWrap.cs b/Assets/LuaFramework/ToLua/BaseType/UnityEngine_MeshRendererWrap.cs deleted file mode 100644 index acf1f5d..0000000 --- a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_MeshRendererWrap.cs +++ /dev/null @@ -1,273 +0,0 @@ -//this source code was auto-generated by tolua#, do not modify it -using System; -using LuaInterface; - -public class UnityEngine_MeshRendererWrap -{ - public static void Register(LuaState L) - { - L.BeginClass(typeof(UnityEngine.MeshRenderer), typeof(UnityEngine.Renderer)); - L.RegFunction("New", _CreateUnityEngine_MeshRenderer); - L.RegFunction("__eq", op_Equality); - L.RegFunction("__tostring", ToLua.op_ToString); - L.RegVar("additionalVertexStreams", get_additionalVertexStreams, set_additionalVertexStreams); - L.RegVar("enlightenVertexStream", get_enlightenVertexStream, set_enlightenVertexStream); - L.RegVar("subMeshStartIndex", get_subMeshStartIndex, null); - // L.RegVar("scaleInLightmap", get_scaleInLightmap, set_scaleInLightmap); - // L.RegVar("receiveGI", get_receiveGI, set_receiveGI); - // L.RegVar("stitchLightmapSeams", get_stitchLightmapSeams, set_stitchLightmapSeams); - L.EndClass(); - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int _CreateUnityEngine_MeshRenderer(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 0) - { - UnityEngine.MeshRenderer obj = new UnityEngine.MeshRenderer(); - ToLua.Push(L, obj); - return 1; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: UnityEngine.MeshRenderer.New"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int op_Equality(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.ToObject(L, 1); - UnityEngine.Object arg1 = (UnityEngine.Object)ToLua.ToObject(L, 2); - bool o = arg0 == arg1; - LuaDLL.lua_pushboolean(L, o); - return 1; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_additionalVertexStreams(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - UnityEngine.Mesh ret = obj.additionalVertexStreams; - ToLua.PushSealed(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index additionalVertexStreams on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_enlightenVertexStream(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - UnityEngine.Mesh ret = obj.enlightenVertexStream; - ToLua.PushSealed(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index enlightenVertexStream on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_subMeshStartIndex(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - int ret = obj.subMeshStartIndex; - LuaDLL.lua_pushinteger(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index subMeshStartIndex on a nil value"); - } - } - - // [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - // static int get_scaleInLightmap(IntPtr L) - // { - // object o = null; - - // try - // { - // o = ToLua.ToObject(L, 1); - // UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - // float ret = obj.scaleInLightmap; - // LuaDLL.lua_pushnumber(L, ret); - // return 1; - // } - // catch(Exception e) - // { - // return LuaDLL.toluaL_exception(L, e, o, "attempt to index scaleInLightmap on a nil value"); - // } - // } - - // [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - // static int get_receiveGI(IntPtr L) - // { - // object o = null; - - // try - // { - // o = ToLua.ToObject(L, 1); - // UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - // UnityEngine.ReceiveGI ret = obj.receiveGI; - // ToLua.Push(L, ret); - // return 1; - // } - // catch(Exception e) - // { - // return LuaDLL.toluaL_exception(L, e, o, "attempt to index receiveGI on a nil value"); - // } - // } - - // [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - // static int get_stitchLightmapSeams(IntPtr L) - // { - // object o = null; - - // try - // { - // o = ToLua.ToObject(L, 1); - // UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - // bool ret = obj.stitchLightmapSeams; - // LuaDLL.lua_pushboolean(L, ret); - // return 1; - // } - // catch(Exception e) - // { - // return LuaDLL.toluaL_exception(L, e, o, "attempt to index stitchLightmapSeams on a nil value"); - // } - // } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_additionalVertexStreams(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - UnityEngine.Mesh arg0 = (UnityEngine.Mesh)ToLua.CheckObject(L, 2, typeof(UnityEngine.Mesh)); - obj.additionalVertexStreams = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index additionalVertexStreams on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_enlightenVertexStream(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - UnityEngine.Mesh arg0 = (UnityEngine.Mesh)ToLua.CheckObject(L, 2, typeof(UnityEngine.Mesh)); - obj.enlightenVertexStream = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index enlightenVertexStream on a nil value"); - } - } - - // [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - // static int set_scaleInLightmap(IntPtr L) - // { - // object o = null; - - // try - // { - // o = ToLua.ToObject(L, 1); - // UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - // float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - // obj.scaleInLightmap = arg0; - // return 0; - // } - // catch(Exception e) - // { - // return LuaDLL.toluaL_exception(L, e, o, "attempt to index scaleInLightmap on a nil value"); - // } - // } - - // [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - // static int set_receiveGI(IntPtr L) - // { - // object o = null; - - // try - // { - // o = ToLua.ToObject(L, 1); - // UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - // UnityEngine.ReceiveGI arg0 = (UnityEngine.ReceiveGI)ToLua.CheckObject(L, 2, typeof(UnityEngine.ReceiveGI)); - // obj.receiveGI = arg0; - // return 0; - // } - // catch(Exception e) - // { - // return LuaDLL.toluaL_exception(L, e, o, "attempt to index receiveGI on a nil value"); - // } - // } - - // [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - // static int set_stitchLightmapSeams(IntPtr L) - // { - // object o = null; - - // try - // { - // o = ToLua.ToObject(L, 1); - // UnityEngine.MeshRenderer obj = (UnityEngine.MeshRenderer)o; - // bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - // obj.stitchLightmapSeams = arg0; - // return 0; - // } - // catch(Exception e) - // { - // return LuaDLL.toluaL_exception(L, e, o, "attempt to index stitchLightmapSeams on a nil value"); - // } - // } -} - diff --git a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_ParticleSystemWrap.cs b/Assets/LuaFramework/ToLua/BaseType/UnityEngine_ParticleSystemWrap.cs deleted file mode 100644 index b16c8de..0000000 --- a/Assets/LuaFramework/ToLua/BaseType/UnityEngine_ParticleSystemWrap.cs +++ /dev/null @@ -1,1392 +0,0 @@ -//this source code was auto-generated by tolua#, do not modify it -using System; -using LuaInterface; - -public class UnityEngine_ParticleSystemWrap -{ - public static void Register(LuaState L) - { - L.BeginClass(typeof(UnityEngine.ParticleSystem), typeof(UnityEngine.Component)); - L.RegFunction("SetParticles", SetParticles); - L.RegFunction("GetParticles", GetParticles); - L.RegFunction("SetCustomParticleData", SetCustomParticleData); - L.RegFunction("GetCustomParticleData", GetCustomParticleData); - L.RegFunction("GetPlaybackState", GetPlaybackState); - L.RegFunction("SetPlaybackState", SetPlaybackState); - L.RegFunction("GetTrails", GetTrails); - L.RegFunction("SetTrails", SetTrails); - L.RegFunction("Simulate", Simulate); - L.RegFunction("Play", Play); - L.RegFunction("Pause", Pause); - L.RegFunction("Stop", Stop); - L.RegFunction("Clear", Clear); - L.RegFunction("IsAlive", IsAlive); - L.RegFunction("Emit", Emit); - L.RegFunction("TriggerSubEmitter", TriggerSubEmitter); - L.RegFunction("ResetPreMappedBufferMemory", ResetPreMappedBufferMemory); - L.RegFunction("SetMaximumPreMappedBufferCounts", SetMaximumPreMappedBufferCounts); - L.RegFunction("AllocateAxisOfRotationAttribute", AllocateAxisOfRotationAttribute); - L.RegFunction("AllocateMeshIndexAttribute", AllocateMeshIndexAttribute); - L.RegFunction("AllocateCustomDataAttribute", AllocateCustomDataAttribute); - L.RegFunction("New", _CreateUnityEngine_ParticleSystem); - L.RegFunction("__eq", op_Equality); - L.RegFunction("__tostring", ToLua.op_ToString); - L.RegVar("isPlaying", get_isPlaying, null); - L.RegVar("isEmitting", get_isEmitting, null); - L.RegVar("isStopped", get_isStopped, null); - L.RegVar("isPaused", get_isPaused, null); - L.RegVar("particleCount", get_particleCount, null); - L.RegVar("time", get_time, set_time); - L.RegVar("randomSeed", get_randomSeed, set_randomSeed); - L.RegVar("useAutoRandomSeed", get_useAutoRandomSeed, set_useAutoRandomSeed); - L.RegVar("proceduralSimulationSupported", get_proceduralSimulationSupported, null); - L.RegVar("main", get_main, null); - L.RegVar("emission", get_emission, null); - L.RegVar("shape", get_shape, null); - L.RegVar("velocityOverLifetime", get_velocityOverLifetime, null); - L.RegVar("limitVelocityOverLifetime", get_limitVelocityOverLifetime, null); - L.RegVar("inheritVelocity", get_inheritVelocity, null); - L.RegVar("lifetimeByEmitterSpeed", get_lifetimeByEmitterSpeed, null); - L.RegVar("forceOverLifetime", get_forceOverLifetime, null); - L.RegVar("colorOverLifetime", get_colorOverLifetime, null); - L.RegVar("colorBySpeed", get_colorBySpeed, null); - L.RegVar("sizeOverLifetime", get_sizeOverLifetime, null); - L.RegVar("sizeBySpeed", get_sizeBySpeed, null); - L.RegVar("rotationOverLifetime", get_rotationOverLifetime, null); - L.RegVar("rotationBySpeed", get_rotationBySpeed, null); - L.RegVar("externalForces", get_externalForces, null); - L.RegVar("noise", get_noise, null); - L.RegVar("collision", get_collision, null); - L.RegVar("trigger", get_trigger, null); - L.RegVar("subEmitters", get_subEmitters, null); - L.RegVar("textureSheetAnimation", get_textureSheetAnimation, null); - L.RegVar("lights", get_lights, null); - L.RegVar("trails", get_trails, null); - L.RegVar("customData", get_customData, null); - L.EndClass(); - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int _CreateUnityEngine_ParticleSystem(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 0) - { - UnityEngine.ParticleSystem obj = new UnityEngine.ParticleSystem(); - ToLua.PushSealed(L, obj); - return 1; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: UnityEngine.ParticleSystem.New"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int SetParticles(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 2 && TypeChecker.CheckTypes>(L, 2)) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.Particle[] arg0 = null; - obj.SetParticles(arg0); - return 0; - } - // else if (count == 2 && TypeChecker.CheckTypes(L, 2)) - // { - // UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - // Unity.Collections.NativeArray arg0; - // obj.SetParticles(arg0); - // return 0; - // } - else if (count == 3 && TypeChecker.CheckTypes, int>(L, 2)) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.Particle[] arg0 = null; - int arg1 = (int)LuaDLL.lua_tonumber(L, 3); - obj.SetParticles(arg0, arg1); - return 0; - } - // else if (count == 3 && TypeChecker.CheckTypes(L, 2)) - // { - // UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - // Unity.Collections.NativeArray arg0; - // int arg1 = (int)LuaDLL.lua_tonumber(L, 3); - // obj.SetParticles(arg0, arg1); - // return 0; - // } - else if (count == 4 && TypeChecker.CheckTypes, int, int>(L, 2)) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.Particle[] arg0 = null; - int arg1 = (int)LuaDLL.lua_tonumber(L, 3); - int arg2 = (int)LuaDLL.lua_tonumber(L, 4); - obj.SetParticles(arg0, arg1, arg2); - return 0; - } - // else if (count == 4 && TypeChecker.CheckTypes(L, 2)) - // { - // UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - // Unity.Collections.NativeArray arg0; - // int arg1 = (int)LuaDLL.lua_tonumber(L, 3); - // int arg2 = (int)LuaDLL.lua_tonumber(L, 4); - // obj.SetParticles(arg0, arg1, arg2); - // return 0; - // } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.SetParticles"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int GetParticles(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 2 && TypeChecker.CheckTypes>(L, 2)) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.Particle[] arg0 = null; - int o = obj.GetParticles(arg0); - LuaDLL.lua_pushinteger(L, o); - return 1; - } - // else if (count == 2 && TypeChecker.CheckTypes(L, 2)) - // { - // UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - // Unity.Collections.NativeArray arg0; - // int o = obj.GetParticles(arg0); - // LuaDLL.lua_pushinteger(L, o); - // return 1; - // } - else if (count == 3 && TypeChecker.CheckTypes, int>(L, 2)) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.Particle[] arg0 = null; - int arg1 = (int)LuaDLL.lua_tonumber(L, 3); - int o = obj.GetParticles(arg0, arg1); - LuaDLL.lua_pushinteger(L, o); - return 1; - } - // else if (count == 3 && TypeChecker.CheckTypes(L, 2)) - // { - // UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - // Unity.Collections.NativeArray arg0; - // int arg1 = (int)LuaDLL.lua_tonumber(L, 3); - // int o = obj.GetParticles(arg0, arg1); - // LuaDLL.lua_pushinteger(L, o); - // return 1; - // } - else if (count == 4 && TypeChecker.CheckTypes, int, int>(L, 2)) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.Particle[] arg0 = null; - int arg1 = (int)LuaDLL.lua_tonumber(L, 3); - int arg2 = (int)LuaDLL.lua_tonumber(L, 4); - int o = obj.GetParticles(arg0, arg1, arg2); - LuaDLL.lua_pushinteger(L, o); - return 1; - } - // else if (count == 4 && TypeChecker.CheckTypes(L, 2)) - // { - // UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - // Unity.Collections.NativeArray arg0; - // int arg1 = (int)LuaDLL.lua_tonumber(L, 3); - // int arg2 = (int)LuaDLL.lua_tonumber(L, 4); - // int o = obj.GetParticles(arg0, arg1, arg2); - // LuaDLL.lua_pushinteger(L, o); - // return 1; - // } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.GetParticles"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int SetCustomParticleData(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 3); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - System.Collections.Generic.List arg0 = (System.Collections.Generic.List)ToLua.CheckObject(L, 2, typeof(System.Collections.Generic.List)); - UnityEngine.ParticleSystemCustomData arg1 = (UnityEngine.ParticleSystemCustomData)ToLua.CheckObject(L, 3, typeof(UnityEngine.ParticleSystemCustomData)); - obj.SetCustomParticleData(arg0, arg1); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int GetCustomParticleData(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 3); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - System.Collections.Generic.List arg0 = (System.Collections.Generic.List)ToLua.CheckObject(L, 2, typeof(System.Collections.Generic.List)); - UnityEngine.ParticleSystemCustomData arg1 = (UnityEngine.ParticleSystemCustomData)ToLua.CheckObject(L, 3, typeof(UnityEngine.ParticleSystemCustomData)); - int o = obj.GetCustomParticleData(arg0, arg1); - LuaDLL.lua_pushinteger(L, o); - return 1; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int GetPlaybackState(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.PlaybackState o = obj.GetPlaybackState(); - ToLua.PushValue(L, o); - return 1; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int SetPlaybackState(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.PlaybackState arg0 = StackTraits.Check(L, 2); - obj.SetPlaybackState(arg0); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int GetTrails(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.Trails o = obj.GetTrails(); - ToLua.PushValue(L, o); - return 1; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int SetTrails(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.Trails arg0 = StackTraits.Check(L, 2); - obj.SetTrails(arg0); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int Simulate(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 2) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.Simulate(arg0); - return 0; - } - else if (count == 3) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - bool arg1 = LuaDLL.luaL_checkboolean(L, 3); - obj.Simulate(arg0, arg1); - return 0; - } - else if (count == 4) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - bool arg1 = LuaDLL.luaL_checkboolean(L, 3); - bool arg2 = LuaDLL.luaL_checkboolean(L, 4); - obj.Simulate(arg0, arg1, arg2); - return 0; - } - else if (count == 5) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - bool arg1 = LuaDLL.luaL_checkboolean(L, 3); - bool arg2 = LuaDLL.luaL_checkboolean(L, 4); - bool arg3 = LuaDLL.luaL_checkboolean(L, 5); - obj.Simulate(arg0, arg1, arg2, arg3); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.Simulate"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int Play(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 1) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - obj.Play(); - return 0; - } - else if (count == 2) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.Play(arg0); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.Play"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int Pause(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 1) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - obj.Pause(); - return 0; - } - else if (count == 2) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.Pause(arg0); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.Pause"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int Stop(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 1) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - obj.Stop(); - return 0; - } - else if (count == 2) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.Stop(arg0); - return 0; - } - else if (count == 3) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - UnityEngine.ParticleSystemStopBehavior arg1 = (UnityEngine.ParticleSystemStopBehavior)ToLua.CheckObject(L, 3, typeof(UnityEngine.ParticleSystemStopBehavior)); - obj.Stop(arg0, arg1); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.Stop"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int Clear(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 1) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - obj.Clear(); - return 0; - } - else if (count == 2) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.Clear(arg0); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.Clear"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int IsAlive(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 1) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - bool o = obj.IsAlive(); - LuaDLL.lua_pushboolean(L, o); - return 1; - } - else if (count == 2) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - bool o = obj.IsAlive(arg0); - LuaDLL.lua_pushboolean(L, o); - return 1; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.IsAlive"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int Emit(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 2) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); - obj.Emit(arg0); - return 0; - } - else if (count == 3) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystem.EmitParams arg0 = StackTraits.Check(L, 2); - int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); - obj.Emit(arg0, arg1); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.Emit"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int TriggerSubEmitter(IntPtr L) - { - try - { - int count = LuaDLL.lua_gettop(L); - - if (count == 2) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); - obj.TriggerSubEmitter(arg0); - return 0; - } - else if (count == 3 && TypeChecker.CheckTypes(L, 3)) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); - UnityEngine.ParticleSystem.Particle arg1 = StackTraits.To(L, 3); - obj.TriggerSubEmitter(arg0, ref arg1); - ToLua.PushValue(L, arg1); - return 1; - } - else if (count == 3 && TypeChecker.CheckTypes>(L, 3)) - { - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); - System.Collections.Generic.List arg1 = (System.Collections.Generic.List)ToLua.ToObject(L, 3); - obj.TriggerSubEmitter(arg0, arg1); - return 0; - } - else - { - return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.ParticleSystem.TriggerSubEmitter"); - } - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int ResetPreMappedBufferMemory(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 0); - UnityEngine.ParticleSystem.ResetPreMappedBufferMemory(); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int SetMaximumPreMappedBufferCounts(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - int arg0 = (int)LuaDLL.luaL_checknumber(L, 1); - int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); - UnityEngine.ParticleSystem.SetMaximumPreMappedBufferCounts(arg0, arg1); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int AllocateAxisOfRotationAttribute(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - obj.AllocateAxisOfRotationAttribute(); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int AllocateMeshIndexAttribute(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - obj.AllocateMeshIndexAttribute(); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int AllocateCustomDataAttribute(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)ToLua.CheckObject(L, 1, typeof(UnityEngine.ParticleSystem)); - UnityEngine.ParticleSystemCustomData arg0 = (UnityEngine.ParticleSystemCustomData)ToLua.CheckObject(L, 2, typeof(UnityEngine.ParticleSystemCustomData)); - obj.AllocateCustomDataAttribute(arg0); - return 0; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int op_Equality(IntPtr L) - { - try - { - ToLua.CheckArgsCount(L, 2); - UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.ToObject(L, 1); - UnityEngine.Object arg1 = (UnityEngine.Object)ToLua.ToObject(L, 2); - bool o = arg0 == arg1; - LuaDLL.lua_pushboolean(L, o); - return 1; - } - catch (Exception e) - { - return LuaDLL.toluaL_exception(L, e); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_isPlaying(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - bool ret = obj.isPlaying; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index isPlaying on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_isEmitting(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - bool ret = obj.isEmitting; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index isEmitting on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_isStopped(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - bool ret = obj.isStopped; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index isStopped on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_isPaused(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - bool ret = obj.isPaused; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index isPaused on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_particleCount(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - int ret = obj.particleCount; - LuaDLL.lua_pushinteger(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index particleCount on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_time(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - float ret = obj.time; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index time on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_randomSeed(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - uint ret = obj.randomSeed; - LuaDLL.lua_pushnumber(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index randomSeed on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_useAutoRandomSeed(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - bool ret = obj.useAutoRandomSeed; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useAutoRandomSeed on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_proceduralSimulationSupported(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - bool ret = obj.proceduralSimulationSupported; - LuaDLL.lua_pushboolean(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index proceduralSimulationSupported on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_main(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.MainModule ret = obj.main; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index main on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_emission(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.EmissionModule ret = obj.emission; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index emission on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_shape(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.ShapeModule ret = obj.shape; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index shape on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_velocityOverLifetime(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.VelocityOverLifetimeModule ret = obj.velocityOverLifetime; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index velocityOverLifetime on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_limitVelocityOverLifetime(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.LimitVelocityOverLifetimeModule ret = obj.limitVelocityOverLifetime; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index limitVelocityOverLifetime on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_inheritVelocity(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.InheritVelocityModule ret = obj.inheritVelocity; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index inheritVelocity on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_lifetimeByEmitterSpeed(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.LifetimeByEmitterSpeedModule ret = obj.lifetimeByEmitterSpeed; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index lifetimeByEmitterSpeed on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_forceOverLifetime(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.ForceOverLifetimeModule ret = obj.forceOverLifetime; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index forceOverLifetime on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_colorOverLifetime(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.ColorOverLifetimeModule ret = obj.colorOverLifetime; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index colorOverLifetime on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_colorBySpeed(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.ColorBySpeedModule ret = obj.colorBySpeed; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index colorBySpeed on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_sizeOverLifetime(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.SizeOverLifetimeModule ret = obj.sizeOverLifetime; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index sizeOverLifetime on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_sizeBySpeed(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.SizeBySpeedModule ret = obj.sizeBySpeed; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index sizeBySpeed on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_rotationOverLifetime(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.RotationOverLifetimeModule ret = obj.rotationOverLifetime; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index rotationOverLifetime on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_rotationBySpeed(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.RotationBySpeedModule ret = obj.rotationBySpeed; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index rotationBySpeed on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_externalForces(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.ExternalForcesModule ret = obj.externalForces; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index externalForces on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_noise(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.NoiseModule ret = obj.noise; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index noise on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_collision(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.CollisionModule ret = obj.collision; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index collision on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_trigger(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.TriggerModule ret = obj.trigger; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index trigger on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_subEmitters(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.SubEmittersModule ret = obj.subEmitters; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index subEmitters on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_textureSheetAnimation(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.TextureSheetAnimationModule ret = obj.textureSheetAnimation; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index textureSheetAnimation on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_lights(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.LightsModule ret = obj.lights; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index lights on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_trails(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.TrailModule ret = obj.trails; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index trails on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int get_customData(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - UnityEngine.ParticleSystem.CustomDataModule ret = obj.customData; - ToLua.PushValue(L, ret); - return 1; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index customData on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_time(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); - obj.time = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index time on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_randomSeed(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - uint arg0 = (uint)LuaDLL.luaL_checknumber(L, 2); - obj.randomSeed = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index randomSeed on a nil value"); - } - } - - [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] - static int set_useAutoRandomSeed(IntPtr L) - { - object o = null; - - try - { - o = ToLua.ToObject(L, 1); - UnityEngine.ParticleSystem obj = (UnityEngine.ParticleSystem)o; - bool arg0 = LuaDLL.luaL_checkboolean(L, 2); - obj.useAutoRandomSeed = arg0; - return 0; - } - catch(Exception e) - { - return LuaDLL.toluaL_exception(L, e, o, "attempt to index useAutoRandomSeed on a nil value"); - } - } -} - diff --git a/Assets/LuaFramework/ToLua/Core/LuaDLL.cs b/Assets/LuaFramework/ToLua/Core/LuaDLL.cs index d83d8c3..dcd873a 100644 --- a/Assets/LuaFramework/ToLua/Core/LuaDLL.cs +++ b/Assets/LuaFramework/ToLua/Core/LuaDLL.cs @@ -19,6 +19,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define LUA_VERSION_5_3 using System; using System.Runtime.InteropServices; diff --git a/Assets/LuaFramework/ToLua/Core/LuaFileUtils.cs b/Assets/LuaFramework/ToLua/Core/LuaFileUtils.cs index b3e6831..3f0f047 100644 --- a/Assets/LuaFramework/ToLua/Core/LuaFileUtils.cs +++ b/Assets/LuaFramework/ToLua/Core/LuaFileUtils.cs @@ -48,16 +48,42 @@ namespace LuaInterface } } - //beZip = false 在search path 中查找读取lua文件。否则从外部设置过来bundel文件中读取lua文件 + //beZip = false 在search path中查找读取lua文件。否则从外部设置过来bundle文件中读取lua文件 public bool beZip = false; protected List searchPaths = new List(); protected Dictionary zipMap = new Dictionary(); + private List m_luaBundleList = new List(); + protected static LuaFileUtils instance = null; public LuaFileUtils() { instance = this; + // Editor下从项目目录里面读取文件 + if (Application.isEditor) + { + beZip = false; + } + } + + public void Init() + { + if (beZip) + { + //update (只有在更新时候用到) + var luaUpdateAb = AssetBundleMgr.instance.LoadAssetBundle("lua_update.bundle"); + if (luaUpdateAb != null) + { + m_luaBundleList.Add(luaUpdateAb); + } + + var luaScriptsAb = AssetBundleMgr.instance.LoadAssetBundle("lua.bundle"); + if (luaScriptsAb != null) + { + m_luaBundleList.Add(luaScriptsAb); + } + } } public virtual void Dispose() @@ -173,10 +199,41 @@ namespace LuaInterface } else { - return ReadZipFile(fileName); + return ReadBytesFromAssetBundle(fileName); } } + /// + /// 读取后缀为非lua的文件 + /// + /// + /// + public string ReadOtherFile(string fileName) + { + if (!beZip) + { + string str = null; + //从项目里面读取 + string filePath = LuaConst.luaDir + "/" + fileName; + if (File.Exists(filePath)) + { +#if !UNITY_WEBPLAYER + str = File.ReadAllText(filePath); +#else + throw new LuaException("can't run in web platform, please switch to other platform"); +#endif + } + + return str; + + } + else + { + return ReadStringFromAssetBundle(fileName); + } + + } + public virtual string FindFileError(string fileName) { if (Path.IsPathRooted(fileName)) @@ -273,5 +330,86 @@ namespace LuaInterface { return LuaConst.osDir; } + + /// + /// 从assetbundle中读取bytes文件 + /// + /// + /// + private byte[] ReadBytesFromAssetBundle(string fileName) + { + //使用全名, 避免冲突 + fileName = "Assets/luabundle/" + fileName; + + string bundleFileName = fileName + ".bytes"; + int bundleCount = m_luaBundleList.Count; + for (int i = 0; i < bundleCount; i++) + { + AssetBundle ab = m_luaBundleList[i]; + TextAsset luaCode = ab.LoadAsset(bundleFileName); + if (luaCode == null) + { + //require过来的 没有包含.lua后缀 + string extendStr = Path.GetExtension(fileName); + if (string.IsNullOrEmpty(extendStr)) + { + bundleFileName = fileName + ".lua.bytes"; + luaCode = ab.LoadAsset(bundleFileName); + } + } + + byte[] luaBytes = null; + if (luaCode != null) + { + // 解密 + luaBytes = AESEncrypt.Decrypt(luaCode.bytes); + Resources.UnloadAsset(luaCode); + return luaBytes; + } + } + + GameLogger.LogError("LuaFileUtils.ReadBytesFromAssetBundle " + fileName); + return null; + } + + /// + /// 从assetbundle中读取string + /// + /// + /// + private string ReadStringFromAssetBundle(string fileName) + { + fileName = "Assets/luabundle/" + fileName; + + string bundleFileName = fileName + ".bytes"; + int bundleCount = m_luaBundleList.Count; + for (int i = 0; i < bundleCount; i++) + { + AssetBundle ab = m_luaBundleList[i]; + TextAsset luaCode = ab.LoadAsset(bundleFileName); + if (luaCode == null) + { + //require过来的 没有包含.lua后缀 + string extendStr = Path.GetExtension(fileName); + if (string.IsNullOrEmpty(extendStr)) + { + bundleFileName = fileName + ".lua.bytes"; + luaCode = ab.LoadAsset(bundleFileName); + } + } + + string luaStr = null; + if (luaCode != null) + { + // 解密 + var bytes = AESEncrypt.Decrypt(luaCode.bytes); + // 转字符串 + luaStr = System.Text.Encoding.GetEncoding(65001).GetString(bytes); + Resources.UnloadAsset(luaCode); + return luaStr; + } + } + return null; + } } } diff --git a/Assets/LuaFramework/ToLua/Core/LuaFunction.cs b/Assets/LuaFramework/ToLua/Core/LuaFunction.cs index 43fdd8b..cd8a0e6 100644 --- a/Assets/LuaFramework/ToLua/Core/LuaFunction.cs +++ b/Assets/LuaFramework/ToLua/Core/LuaFunction.cs @@ -376,7 +376,7 @@ namespace LuaInterface EndPCall(); throw new LuaException("stack overflow"); } - + PushArgs(args); PCall(); object[] objs = luaState.CheckObjects(oldTop); diff --git a/Assets/LuaFramework/ToLua/Core/LuaState.cs b/Assets/LuaFramework/ToLua/Core/LuaState.cs index 6b5e4d8..8c66695 100644 --- a/Assets/LuaFramework/ToLua/Core/LuaState.cs +++ b/Assets/LuaFramework/ToLua/Core/LuaState.cs @@ -20,6 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define MISS_WARNING +#define LUA_VERSION_5_3 using System; using System.IO; @@ -162,9 +163,6 @@ namespace LuaInterface BeginModule("UnityEngine"); UnityEngine_ObjectWrap.Register(this); UnityEngine_CoroutineWrap.Register(this); - UnityEngine_ParticleSystemWrap.Register(this); - UnityEngine_LightWrap.Register(this); - UnityEngine_MeshRendererWrap.Register(this); EndModule(); //end UnityEngine EndModule(); //end global @@ -291,7 +289,11 @@ namespace LuaInterface if (string.IsNullOrEmpty(name)) { +#if LUA_VERSION_5_3 + LuaDLL.tolua_pushglobaltable(L); +#else LuaDLL.lua_pushvalue(L, LuaIndexes.LUA_GLOBALSINDEX); +#endif ++beginCount; return top; } @@ -590,7 +592,7 @@ namespace LuaInterface #endif } - public void DoString(string chunk, string chunkName = "LuaState.cs") + public object[] DoString(string chunk, string chunkName = "LuaState.cs") { #if UNITY_EDITOR if (!beStart) @@ -599,7 +601,7 @@ namespace LuaInterface } #endif byte[] buffer = Encoding.UTF8.GetBytes(chunk); - LuaLoadBuffer(buffer, chunkName); + return LuaLoadBuffer(buffer, chunkName); } public T DoString(string chunk, string chunkName = "LuaState.cs") @@ -638,18 +640,29 @@ namespace LuaInterface return "@" + name; } - public void DoFile(string fileName) + public object[] DoFile(string fileName) { - byte[] buffer = LoadFileBuffer(fileName); - fileName = LuaChunkName(fileName); - LuaLoadBuffer(buffer, fileName); - } +#if UNITY_EDITOR + if (!beStart) + { + throw new LuaException("you must call Start() first to initialize LuaState"); + } +#endif + byte[] buffer = LuaFileUtils.Instance.ReadFile(fileName); - public T DoFile(string fileName) - { - byte[] buffer = LoadFileBuffer(fileName); - fileName = LuaChunkName(fileName); - return LuaLoadBuffer(buffer, fileName); + if (buffer == null) + { + string error = string.Format("cannot open {0}: No such file or directory", fileName); + error += LuaFileUtils.Instance.FindFileError(fileName); + throw new LuaException(error); + } + + //if (LuaConst.openZbsDebugger) + //{ + // fileName = LuaFileUtils.Instance.FindFile(fileName); + //} + + return LuaLoadBuffer(buffer, fileName); } //注意fileName与lua文件中require一致。 @@ -1213,7 +1226,7 @@ namespace LuaInterface } public void Push(Vector3 v3) - { + { LuaDLL.tolua_pushvec3(L, v3.x, v3.y, v3.z); } @@ -1235,7 +1248,7 @@ namespace LuaInterface public void Push(Quaternion q) { LuaDLL.tolua_pushquat(L, q.x, q.y, q.z, q.w); - } + } public void Push(Ray ray) { @@ -1803,7 +1816,11 @@ namespace LuaInterface if (pos > 0) { string tableName = fullPath.Substring(0, pos); +#if LUA_VERSION_5_3 + IntPtr p = LuaDLL.lua_findGlobalTable(L, tableName, 1); +#else IntPtr p = LuaFindTable(LuaIndexes.LUA_GLOBALSINDEX, tableName); +#endif if (p == IntPtr.Zero) { @@ -2087,6 +2104,24 @@ namespace LuaInterface return !(a == b); } + public string GetLuaFunDebugStr() + { + if (funcMap.Count > 0) + { + string str = ""; + foreach (KeyValuePair kvp in funcMap) + { + str += kvp.Key + " "; + } + + return str; + } + else + { + return string.Empty; + } + } + public void PrintTable(string name) { LuaTable table = GetTable(name); @@ -2165,17 +2200,18 @@ namespace LuaInterface } } - protected void LuaLoadBuffer(byte[] buffer, string chunkName) - { - LuaDLL.tolua_pushtraceback(L); + protected object[] LuaLoadBuffer(byte[] buffer, string chunkName) + { + ToLuaPushTraceback(); int oldTop = LuaGetTop(); if (LuaLoadBuffer(buffer, buffer.Length, chunkName) == 0) { if (LuaPCall(0, LuaDLL.LUA_MULTRET, oldTop) == 0) - { + { + object[] result = CheckObjects(oldTop); LuaSetTop(oldTop - 1); - return; + return result; } } diff --git a/Assets/LuaFramework/ToLua/Core/LuaStatePtr.cs b/Assets/LuaFramework/ToLua/Core/LuaStatePtr.cs index 3f987aa..a7bd009 100644 --- a/Assets/LuaFramework/ToLua/Core/LuaStatePtr.cs +++ b/Assets/LuaFramework/ToLua/Core/LuaStatePtr.cs @@ -1,4 +1,6 @@ -using UnityEngine; +#define LUA_VERSION_5_3 + +using UnityEngine; using System; using System.IO; using System.Runtime.InteropServices; @@ -10,67 +12,13 @@ namespace LuaInterface { protected IntPtr L; - string jit = @" - function Euler(x, y, z) - x = x * 0.0087266462599716 - y = y * 0.0087266462599716 - z = z * 0.0087266462599716 - - local sinX = math.sin(x) - local cosX = math.cos(x) - local sinY = math.sin(y) - local cosY = math.cos(y) - local sinZ = math.sin(z) - local cosZ = math.cos(z) - - local w = cosY * cosX * cosZ + sinY * sinX * sinZ - x = cosY* sinX * cosZ + sinY* cosX * sinZ - y = sinY * cosX * cosZ - cosY * sinX * sinZ - z = cosY* cosX * sinZ - sinY* sinX * cosZ - - return {x = x, y = y, z= z, w = w} - end - - function Slerp(q1, q2, t) - local x1, y1, z1, w1 = q1.x, q1.y, q1.z, q1.w - local x2,y2,z2,w2 = q2.x, q2.y, q2.z, q2.w - local dot = x1* x2 + y1* y2 + z1* z2 + w1* w2 - - if dot< 0 then - dot = -dot - x2, y2, z2, w2 = -x2, -y2, -z2, -w2 - end - - if dot< 0.95 then - local sin = math.sin - local angle = math.acos(dot) - local invSinAngle = 1 / sin(angle) - local t1 = sin((1 - t) * angle) * invSinAngle - local t2 = sin(t * angle) * invSinAngle - return {x = x1* t1 + x2* t2, y = y1 * t1 + y2 * t2, z = z1 * t1 + z2 * t2, w = w1 * t1 + w2 * t2} - else - x1 = x1 + t* (x2 - x1) - y1 = y1 + t* (y2 - y1) - z1 = z1 + t* (z2 - z1) - w1 = w1 + t* (w2 - w1) - dot = x1* x1 + y1* y1 + z1* z1 + w1* w1 - - return {x = x1 / dot, y = y1 / dot, z = z1 / dot, w = w1 / dot} - end - end - - if jit then - if jit.status() then - for i=1,10000 do - local q1 = Euler(i, i, i) - Slerp({ x = 0, y = 0, z = 0, w = 1}, q1, 0.5) - end - end - end"; - public int LuaUpValueIndex(int i) { +#if LUA_VERSION_5_3 + return LuaDLL.lua_upvalueindex(i); +#else return LuaIndexes.LUA_GLOBALSINDEX - i; +#endif } public IntPtr LuaNewState() @@ -78,16 +26,6 @@ namespace LuaInterface return LuaDLL.luaL_newstate(); } - public void LuaOpenJit() - { - if (!LuaDLL.luaL_dostring(L, jit)) - { - string str = LuaDLL.lua_tostring(L, -1); - LuaDLL.lua_settop(L, 0); - throw new Exception(str); - } - } - public void LuaClose() { LuaDLL.lua_close(L); @@ -204,10 +142,18 @@ namespace LuaInterface return LuaDLL.lua_tonumber(L, idx); } +#if LUA_VERSION_5_3 + //TODO:暂时先注释(没用到) + //public int LuaToInteger(int idx) + //{ + // return LuaDLL.lua_tointeger(L, idx); + //} +#else public int LuaToInteger(int idx) { return LuaDLL.lua_tointeger(L, idx); } +#endif public bool LuaToBoolean(int idx) { @@ -329,10 +275,12 @@ namespace LuaInterface return LuaDLL.lua_getmetatable(L, idx); } +#if !LUA_VERSION_5_3 public void LuaGetEnv(int idx) { LuaDLL.lua_getfenv(L, idx); } +#endif public void LuaSetTable(int idx) { @@ -359,10 +307,12 @@ namespace LuaInterface LuaDLL.lua_setmetatable(L, objIndex); } +#if !LUA_VERSION_5_3 public void LuaSetEnv(int idx) { LuaDLL.lua_setfenv(L, idx); } +#endif public void LuaCall(int nArgs, int nResults) { @@ -461,11 +411,13 @@ namespace LuaInterface return LuaDLL.lua_type(L, n) <= LuaTypes.LUA_TNIL; } +#if !LUA_VERSION_5_3 public void LuaRawGlobal(string name) { LuaDLL.lua_pushstring(L, name); LuaDLL.lua_rawget(L, LuaIndexes.LUA_GLOBALSINDEX); } +#endif public void LuaSetGlobal(string name) { @@ -497,10 +449,12 @@ namespace LuaInterface return LuaDLL.luaL_checknumber(L, stackPos); } +#if !LUA_VERSION_5_3 public int LuaCheckInteger(int idx) { return LuaDLL.luaL_checkinteger(L, idx); } +#endif public bool LuaCheckBoolean(int stackPos) { @@ -517,10 +471,12 @@ namespace LuaInterface return LuaDLL.luaL_loadbuffer(L, buff, size, name); } + #if !LUA_VERSION_5_3 public IntPtr LuaFindTable(int idx, string fname, int szhint = 1) { return LuaDLL.luaL_findtable(L, idx, fname, szhint); } +#endif public int LuaTypeError(int stackPos, string tname, string t2 = null) { @@ -624,7 +580,6 @@ namespace LuaInterface public void OpenToLuaLibs() { LuaDLL.tolua_openlibs(L); - LuaOpenJit(); } public void ToLuaPushTraceback() diff --git a/Assets/LuaFramework/ToLua/Core/ToLua.cs b/Assets/LuaFramework/ToLua/Core/ToLua.cs index ef9733a..0eec092 100644 --- a/Assets/LuaFramework/ToLua/Core/ToLua.cs +++ b/Assets/LuaFramework/ToLua/Core/ToLua.cs @@ -19,6 +19,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define LUA_VERSION_5_3 + using UnityEngine; using System; using System.Diagnostics; @@ -108,7 +110,11 @@ namespace LuaInterface LuaDLL.lua_pop(L, 1); LuaDLL.tolua_pushudata(L, 1); +#if LUA_VERSION_5_3 + LuaDLL.lua_setglobal(L, "null"); +#else LuaDLL.lua_setfield(L, LuaIndexes.LUA_GLOBALSINDEX, "null"); +#endif #if UNITY_EDITOR GetToLuaInstanceID(); diff --git a/Assets/LuaFramework/ToLua/Misc/LuaLooper.cs b/Assets/LuaFramework/ToLua/Misc/LuaLooper.cs index df818c9..a24573e 100644 --- a/Assets/LuaFramework/ToLua/Misc/LuaLooper.cs +++ b/Assets/LuaFramework/ToLua/Misc/LuaLooper.cs @@ -23,66 +23,81 @@ using System; using UnityEngine; using LuaInterface; -public class LuaLooper : MonoBehaviour -{ - public LuaBeatEvent UpdateEvent +public class LuaLooper +{ + private static LuaLooper mInstance; + public static LuaLooper instance { - get; - private set; - } - - public LuaBeatEvent LateUpdateEvent - { - get; - private set; + get + { + if (mInstance == null) + mInstance = new LuaLooper(); + return mInstance; + } } - public LuaBeatEvent FixedUpdateEvent - { - get; - private set; - } + // public LuaBeatEvent UpdateEvent + // { + // get; + // private set; + // } - public LuaState luaState = null; + // public LuaBeatEvent LateUpdateEvent + // { + // get; + // private set; + // } - void Start() - { - try - { - UpdateEvent = GetEvent("UpdateBeat"); - LateUpdateEvent = GetEvent("LateUpdateBeat"); - FixedUpdateEvent = GetEvent("FixedUpdateBeat"); - } - catch (Exception e) - { - Destroy(this); - throw e; - } - } + // public LuaBeatEvent FixedUpdateEvent + // { + // get; + // private set; + // } - LuaBeatEvent GetEvent(string name) + public LuaState luaState = null; + public void OnInit(LuaState state) { - LuaTable table = luaState.GetTable(name); - - if (table == null) - { - throw new LuaException(string.Format("Lua table {0} not exists", name)); - } - - LuaBeatEvent e = new LuaBeatEvent(table); - table.Dispose(); - table = null; - return e; + luaState = state; } + // void Start() + // { + // try + // { + // UpdateEvent = GetEvent("UpdateBeat"); + // LateUpdateEvent = GetEvent("LateUpdateBeat"); + // FixedUpdateEvent = GetEvent("FixedUpdateBeat"); + // } + // catch (Exception e) + // { + // Destroy(this); + // throw e; + // } + // } + + // LuaBeatEvent GetEvent(string name) + // { + // LuaTable table = luaState.GetTable(name); + + // if (table == null) + // { + // throw new LuaException(string.Format("Lua table {0} not exists", name)); + // } + + // LuaBeatEvent e = new LuaBeatEvent(table); + // table.Dispose(); + // table = null; + // return e; + // } + void ThrowException() { string error = luaState.LuaToString(-1); - luaState.LuaPop(2); + luaState.LuaPop(2); throw new LuaException(error, LuaException.GetLastError()); } - void Update() + public void Update() { #if UNITY_EDITOR if (luaState == null) @@ -102,7 +117,7 @@ public class LuaLooper : MonoBehaviour #endif } - void LateUpdate() + public void LateUpdate() { #if UNITY_EDITOR if (luaState == null) @@ -118,7 +133,7 @@ public class LuaLooper : MonoBehaviour luaState.LuaPop(1); } - void FixedUpdate() + public void FixedUpdate() { #if UNITY_EDITOR if (luaState == null) @@ -138,33 +153,33 @@ public class LuaLooper : MonoBehaviour { if (luaState != null) { - if (UpdateEvent != null) - { - UpdateEvent.Dispose(); - UpdateEvent = null; - } - - if (LateUpdateEvent != null) - { - LateUpdateEvent.Dispose(); - LateUpdateEvent = null; - } - - if (FixedUpdateEvent != null) - { - FixedUpdateEvent.Dispose(); - FixedUpdateEvent = null; - } + // if (UpdateEvent != null) + // { + // UpdateEvent.Dispose(); + // UpdateEvent = null; + // } + + // if (LateUpdateEvent != null) + // { + // LateUpdateEvent.Dispose(); + // LateUpdateEvent = null; + // } + + // if (FixedUpdateEvent != null) + // { + // FixedUpdateEvent.Dispose(); + // FixedUpdateEvent = null; + // } luaState = null; } } - void OnDestroy() - { - if (luaState != null) - { - Destroy(); - } - } + // void OnDestroy() + // { + // if (luaState != null) + // { + // Destroy(); + // } + // } } diff --git a/Assets/Editor/Utils.meta b/Assets/Scripts/Framework/Common.meta similarity index 77% rename from Assets/Editor/Utils.meta rename to Assets/Scripts/Framework/Common.meta index b188a06..6226a4c 100644 --- a/Assets/Editor/Utils.meta +++ b/Assets/Scripts/Framework/Common.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6ce69a05436d282419ee413ea9e516e1 +guid: cad0f9b8154b9f34fbe8f3723d4a9452 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/LuaFramework/Luajit/jit.meta b/Assets/Scripts/Framework/Common/Global.meta similarity index 58% rename from Assets/LuaFramework/Luajit/jit.meta rename to Assets/Scripts/Framework/Common/Global.meta index 1c64772..03c3275 100644 --- a/Assets/LuaFramework/Luajit/jit.meta +++ b/Assets/Scripts/Framework/Common/Global.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 -guid: 91ba6b2190e00254aa340e1e35dadcb4 +guid: b5f6fdb52e91e9b4c8d8d18d11c86934 folderAsset: yes -timeCreated: 1498139739 -licenseType: Pro DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Scripts/Framework/Common/Global/GlobalObjs.cs b/Assets/Scripts/Framework/Common/Global/GlobalObjs.cs new file mode 100644 index 0000000..f2a01a6 --- /dev/null +++ b/Assets/Scripts/Framework/Common/Global/GlobalObjs.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +/// +/// 全局物体 +/// +public class GlobalObjs +{ + public static Canvas sCanvas; + public static Transform sTopPanel; +} \ No newline at end of file diff --git a/Assets/Scripts/Framework/Common/Global/GlobalObjs.cs.meta b/Assets/Scripts/Framework/Common/Global/GlobalObjs.cs.meta new file mode 100644 index 0000000..dd7a1af --- /dev/null +++ b/Assets/Scripts/Framework/Common/Global/GlobalObjs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99ffca80ac524784eaa9cef15d4c38bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LuaFramework/Luajit/Build.bat.meta b/Assets/Scripts/Framework/Common/Misc.meta similarity index 54% rename from Assets/LuaFramework/Luajit/Build.bat.meta rename to Assets/Scripts/Framework/Common/Misc.meta index 1d3cd92..57b7d02 100644 --- a/Assets/LuaFramework/Luajit/Build.bat.meta +++ b/Assets/Scripts/Framework/Common/Misc.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: 3717a1ffedc585945a43193f52a32f26 -timeCreated: 1498139739 -licenseType: Pro +guid: 7443a744495250f4985bebfff05f1267 +folderAsset: yes DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Scripts/Framework/Common/Misc/ObjectParser.cs b/Assets/Scripts/Framework/Common/Misc/ObjectParser.cs new file mode 100644 index 0000000..5807c8c --- /dev/null +++ b/Assets/Scripts/Framework/Common/Misc/ObjectParser.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using System.Xml; +using System; + +/// +/// 解析xml进行字段反射 +/// +public static class ObjectParser +{ + public enum Result + { + OK, + FieldNotExist, + InvalidEnum, + FormatError, + } + + public static string lastError { get; private set; } + + private delegate object StringConverter(string raw); + + private static Dictionary _predefinedConverters; + + private delegate TOutput Converter(TInput input); + + static StringConverter MakeConverter(Converter converter) + { + return s => + { + if (string.IsNullOrEmpty(s)) + return default(T); + + return converter(s); + }; + } + + static ObjectParser() + { + _predefinedConverters = new Dictionary(); + _predefinedConverters[typeof(long)] = MakeConverter(Convert.ToInt64); + _predefinedConverters[typeof(ulong)] = MakeConverter(Convert.ToUInt64); + _predefinedConverters[typeof(int)] = MakeConverter(Convert.ToInt32); + _predefinedConverters[typeof(uint)] = MakeConverter(Convert.ToUInt32); + _predefinedConverters[typeof(short)] = MakeConverter(Convert.ToInt16); + _predefinedConverters[typeof(ushort)] = MakeConverter(Convert.ToUInt16); + _predefinedConverters[typeof(byte)] = MakeConverter(Convert.ToByte); + _predefinedConverters[typeof(sbyte)] = MakeConverter(Convert.ToSByte); + _predefinedConverters[typeof(float)] = MakeConverter(Convert.ToSingle); + _predefinedConverters[typeof(double)] = MakeConverter(Convert.ToDouble); + _predefinedConverters[typeof(string)] = s => s ?? ""; + } + + public static Result Parse(XmlNode node, ref object obj, Type type) + { + foreach (XmlNode attrNode in node.Attributes) + { + string fieldName = attrNode.Name; + string fieldValueStr = attrNode.Value; + + var fieldInfo = type.GetField(fieldName); + if (fieldInfo == null) + continue; + + var fieldType = fieldInfo.FieldType; + try + { + StringConverter converter; + if (_predefinedConverters.TryGetValue(fieldType, out converter)) + fieldInfo.SetValue(obj, converter(fieldValueStr)); + else + { + + } + } + catch (FormatException e) + { + lastError = string.Format("format error for field {0}, value is {1}, error message = {2}", fieldName, fieldValueStr, e.Message); + return Result.FormatError; + } + } + return Result.OK; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Framework/Common/Misc/ObjectParser.cs.meta b/Assets/Scripts/Framework/Common/Misc/ObjectParser.cs.meta new file mode 100644 index 0000000..c479315 --- /dev/null +++ b/Assets/Scripts/Framework/Common/Misc/ObjectParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7949b755b67154c4589d058c0a0d9101 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LuaFramework/Luajit/luajit.exe.meta b/Assets/Scripts/Framework/Common/Util.meta similarity index 54% rename from Assets/LuaFramework/Luajit/luajit.exe.meta rename to Assets/Scripts/Framework/Common/Util.meta index 8078bb2..198c09b 100644 --- a/Assets/LuaFramework/Luajit/luajit.exe.meta +++ b/Assets/Scripts/Framework/Common/Util.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: cecf08c1bab22534d9355eecd48576be -timeCreated: 1498139739 -licenseType: Pro +guid: 1af03a5d2d695214ba140c0dacaa0bf8 +folderAsset: yes DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Scripts/Framework/Common/Util/XMLUtil.cs b/Assets/Scripts/Framework/Common/Util/XMLUtil.cs new file mode 100644 index 0000000..c24a14d --- /dev/null +++ b/Assets/Scripts/Framework/Common/Util/XMLUtil.cs @@ -0,0 +1,244 @@ +/******************************************************************* +Description: XML工具 +提供操作XML的辅助函数 +********************************************************************/ + +using System; +using System.Xml; +using System.IO; +using UnityEngine; + + +public class XMLUtil +{ + /// + /// 将xmlContent解析为XmlDocument并返回 + /// + public static XmlDocument getXMLFromString(string content) + { + XmlDocument ret = null; + + ret = new XmlDocument(); + XmlReaderSettings setttings = new XmlReaderSettings(); + setttings.IgnoreComments = true; + setttings.IgnoreWhitespace = true; + + TextReader reader = new StringReader(content); + XmlReader xmlReader = XmlReader.Create(reader, setttings); + + ret.Load(xmlReader); + return ret; + } + + /// + /// 从assetBundle中读取名为xmlName的xml文档,并返回 + /// + public static XmlDocument getXMLFromAssetBundle(AssetBundle assetBundle, string xmlName) + { + string content = GetXmlContent(assetBundle, xmlName); + if (string.IsNullOrEmpty(content)) return null; + return getXMLFromString(content); + } + + public static string GetXmlContent(AssetBundle assetBundle, string xmlName) + { + if(null == assetBundle) + { + GameLogger.LogError("getXMLFromAssetBundle assetBundle == null"); + return null; + } + + TextAsset textAsset = assetBundle.LoadAsset(xmlName, typeof(TextAsset)) as TextAsset; + if(null == textAsset) + { + GameLogger.LogError("getXMLFromAssetBundle textAsset == null"); + return null; + } + + return textAsset.text; + } + + public static XmlDocument getXMLFromFile(string fileName) + { + if (!fileName.EndsWith(".xml") && !fileName.EndsWith(".bytes")) + fileName += ".bytes"; + + if (!File.Exists(fileName)) + { + GameLogger.LogWarning("getXMLFromFile error, file not exist. Path: " + fileName); + return null; + } + + XmlDocument ret = new XmlDocument(); + ret.Load(fileName); + return ret; + } + + public static XmlDocument GetEssentialXmlCfg(string path) + { + XmlDocument ret = null; + //GameLogger.LogGreen(path); + try + { +#if UNITY_EDITOR + ret = getXMLFromFile(ResourcePathBuilder.BuildConfigPath(path)); +#else + AssetBundle ab = AssetBundleMgr.instance.m_normalCfgBundle; + ret = getXMLFromAssetBundle(ab, path); +#endif + } + catch (Exception exp) + { + GameLogger.LogError("get xml cfg error, exp: " + exp.Message + " path: " + path); + } + + return ret; + } + + #region XmlTextReader获取xml文件 + /// + /// 性能优于xmlDocument + /// + /// + /// + public static XmlTextReader GetXmlCfgByReader(string path) + { + XmlTextReader reader = null; + //GameLogger.LogNattierBlue(path); + try + { +#if UNITY_EDITOR + reader = GetXMLFromFile(ResourcePathBuilder.BuildConfigPath(path)); +#else + AssetBundle ab = AssetBundleMgr.instance.m_normalCfgBundle; + reader = GetXMLFromAssetBundle(ab, path); +#endif + } + catch (Exception exp) + { + GameLogger.LogError("get xml cfg error, exp: " + exp.Message + " path: " + path); + } + + return reader; + } + + + public static XmlTextReader GetXMLFromFile(string fileName) + { + if (!fileName.EndsWith(".xml") && !fileName.EndsWith(".bytes")) + fileName += ".bytes"; + + if (!File.Exists(fileName)) + { + GameLogger.LogError("getXMLFromFile error, file not exist. Path: " + fileName); + return null; + } + + return new XmlTextReader(fileName); + } + + public static XmlTextReader GetXMLFromAssetBundle(AssetBundle assetBundle, string xmlName) + { + string content = GetXmlContent(assetBundle, xmlName); + if (string.IsNullOrEmpty(content)) return null; + return GetXMLFromString(content); + } + + /// + /// 将xmlContent解析为XmlDocument并返回 + /// + public static XmlTextReader GetXMLFromString(string content) + { + TextReader reader = new StringReader(content); + return new XmlTextReader(reader); + } + + #endregion + + + public static int tryGetInt32(XmlNode node, string key, int defaultValue) + { + if (null == node.Attributes[key]) return defaultValue; + return XmlConvert.ToInt32(node.Attributes[key].Value); + } + + public static float tryGetFloat(XmlNode node, string key, float defaultValue) + { + if (null == node.Attributes[key]) return defaultValue; + return XmlConvert.ToSingle(node.Attributes[key].Value); + } + + public static string tryGetString(XmlNode node, string key, string defaultValue) + { + if (null == node.Attributes[key]) return defaultValue; + return node.Attributes[key].Value; + } + + + public static int tryGetInt32(XmlTextReader node, string key, int defaultValue) + { + string node_att = node.GetAttribute(key); + if (null == node_att) return defaultValue; + return XmlConvert.ToInt32(node_att); + } + + public static float tryGetFloat(XmlTextReader node, string key, float defaultValue) + { + string node_att = node.GetAttribute(key); + if (null == node_att) return defaultValue; + return XmlConvert.ToSingle(node_att); + } + + public static string tryGetString(XmlTextReader node, string key, string defaultValue) + { + string node_att = node.GetAttribute(key); + if (null == node_att) return defaultValue; + return node_att; + } + + + public static bool filterElement(XmlTextReader reader) + { + if (reader.NodeType != XmlNodeType.Element) return true; + if (reader.Name != "item") return true; + return false; + } + + /// + /// 设置xml的XmlAttribute的值。 + /// 如果没有则创建xml的XmlAttribute。 + /// 如果ignoreNullAndEmpty = true,则检查删除对应的XmlAttribute节点。 + /// + /// + /// + /// + /// 忽视value为空,如果忽视:则不创建xml的XmlAttribute节点,并且删除对应的节点 + public static void SetXmlAttribute(XmlElement xmlEle, string attribute, string value, bool ignoreNullAndEmpty) + { + if (ignoreNullAndEmpty && string.IsNullOrEmpty(value)) + { + xmlEle.RemoveAttribute(attribute); + } + else + { + xmlEle.SetAttribute(attribute, value); + } + } + + /// + /// 写节点属性 + /// + public static void WriteXmlAttributes(XmlDocument doc, XmlNode node, string attributes, string value) + { + if (node.Attributes[attributes] != null) + { + node.Attributes[attributes].Value = value; + } + else + { + XmlAttribute attr = doc.CreateAttribute(attributes); + attr.Value = value; + node.Attributes.Append(attr); + } + } +} diff --git a/Assets/Scripts/Framework/Common/Util/XMLUtil.cs.meta b/Assets/Scripts/Framework/Common/Util/XMLUtil.cs.meta new file mode 100644 index 0000000..bc1420c --- /dev/null +++ b/Assets/Scripts/Framework/Common/Util/XMLUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17ca7133cd664374098999f73cae2f95 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Event/EventDispatcher.cs b/Assets/Scripts/Framework/Event/EventDispatcher.cs index 05a12fc..92255cd 100644 --- a/Assets/Scripts/Framework/Event/EventDispatcher.cs +++ b/Assets/Scripts/Framework/Event/EventDispatcher.cs @@ -18,6 +18,11 @@ public class EventDispatcher private Dictionary> listeners = new Dictionary>(); + /// + /// 注册事件 + /// + /// + /// public void Regist(string key, MyEventHandler handler) { if (handler == null) @@ -35,6 +40,11 @@ public class EventDispatcher listeners[key].Add(handler.GetHashCode(), handler); } + /// + /// 注销事件 + /// + /// + /// public void UnRegist(string key, MyEventHandler handler) { if (handler == null) @@ -51,6 +61,11 @@ public class EventDispatcher } } + /// + /// 抛出事件 + /// + /// + /// public void DispatchEvent(string key, params object[] objs) { if (listeners.ContainsKey(key)) diff --git a/Assets/Scripts/Framework/I18N.meta b/Assets/Scripts/Framework/I18N.meta new file mode 100644 index 0000000..a167c34 --- /dev/null +++ b/Assets/Scripts/Framework/I18N.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 17464e7b74f4060428c40df5a7faf2f5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/I18N/I18CfgItem.cs b/Assets/Scripts/Framework/I18N/I18CfgItem.cs new file mode 100644 index 0000000..9a5c068 --- /dev/null +++ b/Assets/Scripts/Framework/I18N/I18CfgItem.cs @@ -0,0 +1,7 @@ +public class I18CfgItem +{ + public int id; + public string zhCn; + public string zhTw; + public string english; +} \ No newline at end of file diff --git a/Assets/Scripts/Framework/I18N/I18CfgItem.cs.meta b/Assets/Scripts/Framework/I18N/I18CfgItem.cs.meta new file mode 100644 index 0000000..017f888 --- /dev/null +++ b/Assets/Scripts/Framework/I18N/I18CfgItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 942b2663ab3b38046bd306b48bbc84a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/I18N/I18N.cs b/Assets/Scripts/Framework/I18N/I18N.cs new file mode 100644 index 0000000..1126906 --- /dev/null +++ b/Assets/Scripts/Framework/I18N/I18N.cs @@ -0,0 +1,48 @@ +using UnityEngine; +using System.Collections.Generic; + +/// +/// I18国际化文字 +/// +public class I18N +{ + private static I18N mInstance; + public static I18N instance + { + get + { + if (mInstance == null) + mInstance = new I18N(); + return mInstance; + } + } + + private Dictionary mI18nCfg = new Dictionary(); + private bool mIsInited = false; + + public void Init() + { + if (mIsInited) return; + + var reader = XMLUtil.GetXmlCfgByReader("i18nAppStrings"); + while (reader.Read()) + { + if (XMLUtil.filterElement(reader)) continue; + + var key = (int)XMLUtil.tryGetInt32(reader, "key", -1); + var item = new I18CfgItem(); + item.id = key; + item.zhCn = XMLUtil.tryGetString(reader, "value_zh", ""); + item.zhTw = XMLUtil.tryGetString(reader, "value_zh_tw", ""); + item.english = XMLUtil.tryGetString(reader, "english", ""); + mI18nCfg.Add(key, item); + } + mIsInited = true; + } + + public void Reload() + { + mIsInited = false; + Init(); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Framework/I18N/I18N.cs.meta b/Assets/Scripts/Framework/I18N/I18N.cs.meta new file mode 100644 index 0000000..4acdc8f --- /dev/null +++ b/Assets/Scripts/Framework/I18N/I18N.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a22b299716e08694a896505b2d1d0ef5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Log/GameLogger.cs b/Assets/Scripts/Framework/Log/GameLogger.cs index 4e07435..7799f2b 100644 --- a/Assets/Scripts/Framework/Log/GameLogger.cs +++ b/Assets/Scripts/Framework/Log/GameLogger.cs @@ -1,28 +1,29 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; -using System.IO; +/// +/// 游戏日志打印 +/// public class GameLogger { - public static void Init() - { - } - - public static void Log(object msg, UnityEngine.Object context = null) + public static void Log(object msg, Object context = null) { Debug.Log(msg, context); } - public static void LogError(object msg, UnityEngine.Object context = null) + public static void LogError(object msg, Object context = null) { Debug.LogError(msg, context); } - public static void LogGreen(object msg, UnityEngine.Object context = null) + public static void LogGreen(object msg, Object context = null) { Debug.Log(FmtColor("#00ff00", msg), context); } - public static void LogWarning(object msg, UnityEngine.Object context = null) + public static void LogYellow(object msg, Object context = null) + { + Debug.Log(FmtColor("yellow", msg), context); + } + + public static void LogWarning(object msg, Object context = null) { Debug.LogWarning(msg, context); } diff --git a/Assets/Scripts/Framework/Log/LogMgr.cs b/Assets/Scripts/Framework/Log/LogMgr.cs index 10d8512..adaab9d 100644 --- a/Assets/Scripts/Framework/Log/LogMgr.cs +++ b/Assets/Scripts/Framework/Log/LogMgr.cs @@ -1,11 +1,11 @@ -using System.Collections; using UnityEngine; -using UnityEditor; -using LuaFramework; using LuaInterface; using System.IO; using System.Text; +/// +/// 日志管理器 +/// public class LogMgr { public static LogMgr instance @@ -23,16 +23,20 @@ public class LogMgr private StringBuilder sLogStr = new StringBuilder(); // 日志文件存储位置 public string mLogFileSavePath; - + // 输出日志 private string outputStr = ""; [NoToLua] public void Init() { - GameLogger.Init(); - var date = System.DateTime.Now.ToString("yyyyMMddhhmmss"); - mLogFileSavePath = string.Format(AppConst.LOG_UPLOAD_DIR, Application.persistentDataPath, date); +#if UNITY_STANDALONE || UNITY_EDITOR + var logDir = string.Format("{0}/../gamelog/", Application.dataPath); +#else + var logDir = string.Format("{0}/gamelog/", Application.persistentDataPath); +#endif + // 日志文件dir,用于存放本地日志 + mLogFileSavePath = string.Format("{0}/output_{1}.txt", logDir, date); outputStr = ""; // 监听系统日志 diff --git a/Assets/Scripts/Framework/Network.meta b/Assets/Scripts/Framework/Network.meta new file mode 100644 index 0000000..92dfd66 --- /dev/null +++ b/Assets/Scripts/Framework/Network.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8c64294e7b2141a499f7febe4c666666 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Network/ClientNet.cs b/Assets/Scripts/Framework/Network/ClientNet.cs new file mode 100644 index 0000000..ca3e7d3 --- /dev/null +++ b/Assets/Scripts/Framework/Network/ClientNet.cs @@ -0,0 +1,37 @@ +using System; +using UnityEngine; + +public delegate void OnRecvData(SpRpcResult result); + +/// +/// 客户端网络连接 +/// +public class ClientNet : MonoBehaviour +{ + private static ClientNet mInstance; + public static ClientNet instance + { + get + { + if (null == mInstance) + { + GameObject clientNetObj = new GameObject("ClientNet"); + mInstance = clientNetObj.AddComponent(); + } + return mInstance; + } + } + + private RemoteConnection mConnection; + + public bool isConnect { get { return mConnection.isConnect; } } + public bool enableCrypt { get { return mConnection.enableCrypt; } } + + public string resendTarget{ get { return mResendTarget; } set { mResendTarget = value; } } + private string mResendTarget; + + public void AddNetStateListener(INetStateListener listener) + { + mConnection.AddNetStateListener(listener); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Framework/Network/ClientNet.cs.meta b/Assets/Scripts/Framework/Network/ClientNet.cs.meta new file mode 100644 index 0000000..923da6b --- /dev/null +++ b/Assets/Scripts/Framework/Network/ClientNet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f20f95e5e97e414eaef0589a5f3ff43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Network/INetStateListener.cs b/Assets/Scripts/Framework/Network/INetStateListener.cs new file mode 100644 index 0000000..52e7125 --- /dev/null +++ b/Assets/Scripts/Framework/Network/INetStateListener.cs @@ -0,0 +1,16 @@ +public enum NetState +{ + ConnectStart, + ConnectSuccess, + ConnectFail, + Disconnect, + ResendStart, + ResendSuccess, + ResendFail, + Error +} + +public interface INetStateListener +{ + void OnNetStateChanged(NetState state, object param = null); +} \ No newline at end of file diff --git a/Assets/Scripts/Framework/Network/INetStateListener.cs.meta b/Assets/Scripts/Framework/Network/INetStateListener.cs.meta new file mode 100644 index 0000000..bb13e6b --- /dev/null +++ b/Assets/Scripts/Framework/Network/INetStateListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f12a7b0e0314f546b05beda48a81161 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Network/NetDataAnalysis.cs b/Assets/Scripts/Framework/Network/NetDataAnalysis.cs new file mode 100644 index 0000000..ab17113 --- /dev/null +++ b/Assets/Scripts/Framework/Network/NetDataAnalysis.cs @@ -0,0 +1,115 @@ +using System.Collections.Generic; +using System.Text; + +/// +/// 网络分析类 +/// +public class NetDataAnalysis +{ + private static NetDataAnalysis _instance; + public static NetDataAnalysis GetInstance() + { + lock (typeof(NetDataAnalysis)) + { + if (_instance == null) + { + _instance = new NetDataAnalysis(); + } + + return _instance; + } + } + + private Dictionary m_sendMsgDic = new Dictionary(); + private Dictionary m_receiveMsgDic = new Dictionary(); + private StringBuilder m_stringBuilder = new StringBuilder(); + + protected void AddSendData(string proto, int size) + { + int count; + if(m_sendMsgDic.TryGetValue(proto, out count)) + { + m_sendMsgDic[proto] = count + size; + } + else + { + m_sendMsgDic.Add(proto, size); + } + } + + protected void AddReceiveData(string proto, int size) + { + int count; + if (m_receiveMsgDic.TryGetValue(proto, out count)) + { + m_receiveMsgDic[proto] = count + size; + } + else + { + m_receiveMsgDic.Add(proto, size); + } + } + + + public string GetDeBugInfo() + { + if (m_stringBuilder.Length > 0) + { + m_stringBuilder.Remove(0, m_stringBuilder.Length - 1); + } + + + int totalSendSize = 0; + + foreach (KeyValuePair kvp in m_sendMsgDic) + { + totalSendSize += kvp.Value; + m_stringBuilder.AppendFormat("Proto:{0},Size:{1}Byte/{2:N3}KB/{3:N6}M ", kvp.Key, kvp.Value, kvp.Value / 1024.0f, kvp.Value / 1024.0f / 1024.0f); + } + + m_stringBuilder.Append("\n"); + m_stringBuilder.AppendFormat(I18N.GetStr(2), totalSendSize, totalSendSize / 1024.0f, totalSendSize / 1024.0f / 1024.0f);//2="发送流量: {0}Byte/{1:N3}KB/{2:N6}M \n" + + int totalReceiveSize = 0; + + foreach (KeyValuePair kvp in m_receiveMsgDic) + { + totalReceiveSize += kvp.Value; + m_stringBuilder.AppendFormat("Proto:{0},Size:{1}Byte/{2:N3}KB/{3:N6}M ", kvp.Key, kvp.Value, kvp.Value / 1024.0f, kvp.Value / 1024.0f / 1024.0f); + } + m_stringBuilder.Append("\n"); + m_stringBuilder.AppendFormat(I18N.GetStr(3), totalReceiveSize, totalReceiveSize / 1024.0f, totalReceiveSize / 1024.0f / 1024.0f);//3="接受总流量: {0}Byte/{1:N3}KB/{2:N6}M \n" + + return m_stringBuilder.ToString(); + } + + + + private static bool m_openAnalysis = false; + + public static void SetOpenNetAnalysis(bool bOpen) + { + m_openAnalysis = bOpen; + } + public static bool GetOpenAnalysis() + { + return m_openAnalysis; + } + + public static void SendData(string proto, byte[] data) + { + if(m_openAnalysis) + { + NetDataAnalysis.GetInstance().AddSendData(proto, data.Length); + } + } + + public static void RecieveData(SpRpcResult spResult, SpStream spStream) + { + if(m_openAnalysis) + { + NetDataAnalysis.GetInstance().AddReceiveData(spResult.Protocol.Name, spStream.Length); + } + } + +} diff --git a/Assets/Scripts/Framework/Network/NetDataAnalysis.cs.meta b/Assets/Scripts/Framework/Network/NetDataAnalysis.cs.meta new file mode 100644 index 0000000..5a5ea99 --- /dev/null +++ b/Assets/Scripts/Framework/Network/NetDataAnalysis.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c5b46d92123a1e4fb28a180f4779221 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Network/RemoteConnection.cs b/Assets/Scripts/Framework/Network/RemoteConnection.cs new file mode 100644 index 0000000..eea2065 --- /dev/null +++ b/Assets/Scripts/Framework/Network/RemoteConnection.cs @@ -0,0 +1,714 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net.Sockets; +using UnityEngine; + +/// +/// 网络连接 +/// +public class RemoteConnection +{ + public RemoteConnection() + { + m_read = 0; + m_curSession = 0; + m_locker = new object(); + m_recvBuffer = new byte[0x2000]; + m_sendStream = new SpStream(); + m_listeners = new ArrayList(); + m_packQueue = new PackageQueue(); + m_cachePacks = new List(); + m_streamlist = new List(); + m_netStateList = new List(); + m_curNetState = NetState.Disconnect; + recvCallbackFunc = new AsyncCallback(recvCallback); + m_heartbeat = new HeartBeat(this); + } + + public bool Initialize(string s2c, string c2s, string head, OnRecvData recvCallback, bool encrytor = false) + { + try + { + m_rpc = SpRpc.Create(s2c, head); + m_rpc.Attach(c2s); + onRecvDataFunc = recvCallback; + if (onRecvDataFunc == null) throw (new NullReferenceException("onRecvdataFunc == null")); + + + enableCrypt = encrytor; + return true; + } + catch (Exception exp) + { + GameLogger.LogError(exp.ToString()); + return false; + } + } + + public void AddNetStateListener(INetStateListener listener) + { + if (m_listeners != null) + m_listeners.Add(listener); + } + + public bool Connect(string strHost, int port, bool isReconnect = false) + { + try + { + Close(); + m_passTime = 0f; + m_connectCounter = 0f; + m_isReconnect = isReconnect; + // TODO iOS可能需要处理一下ipv6的连接 + + m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + m_socket.SendTimeout = 500; + m_iAsyncResult = m_socket.BeginConnect(strHost, port, null, m_socket); + GameLogger.Log("ClientNet, connect: " + strHost + " port: " + port + " handle: " + m_socket.Handle); + + AddNetState(NetState.ConnectStart, null); + } + catch (Exception exception) + { + Close(); + m_bConnect = false; + GameLogger.LogError(exception.ToString()); + AddNetState(NetState.ConnectFail, null); + } + + return m_bConnect; + } + + public void Send(string proto, SpObject arg) + { + lock (m_locker) + { + //try + { + int length = 0; + byte[] data = null; + m_curSession++; + cachePack(proto, arg); + if (!m_isReconnect) + { + obj2Stream(proto, arg, m_curSession, out data, out length); + send(m_curSession, proto, data, length); + + LuaFramework.NetworkManager.OnSendData(m_curSession, proto); + } + } + //catch (Exception ex) + //{ + // GameLogger.LogWarning(string.Format("Send error, protoName:{0}, exp:{1} ", proto, ex)); + // Util.DumpObject(arg); + //} + } + } + + /// + /// Lua 发送使用接口 + /// + /// 协议名 + /// 消息数据 + /// 消息长度 + /// + /// + public void Send(string proto, byte[] srcData, int srcLen, int session, int tag) + { + lock (m_locker) + { + try + { + //SpStream stream = SpStreamCache.Get(); + //stream.Write(srcData); + //SpRpcResult result = m_rpc.DispatchTest(stream); + m_rpc.AddSession(session, null, tag); + + //都不需要缓存 + //if (!IgnoreResendMsgDef.isIgnore(proto)) + //{ + // m_cachePacks.Add(new CachePackInfo(session, proto, null)); + //} + + int length = 0; + byte[] data = null; + EncryptyData(srcData, srcLen, out data, out length); + send(session, proto, data, length); + + LuaFramework.NetworkManager.OnSendData(session, proto); + + } + catch (Exception ex) + { + GameLogger.LogWarning(string.Format("Send error, protoName:{0}, exp:{1} ", proto, ex)); + } + } + } + + public void Resend(bool isUseNewSession = false) + { + int length = 0; + byte[] data = null; + m_resendCounter = 0f; + AddNetState(NetState.ResendStart, null); + for (int i = 0; i < m_cachePacks.Count; ++i) + { + SprotoUtil.DumpObject(m_cachePacks[i].spObj); + if (isUseNewSession) m_cachePacks[i].session = m_curSession++; + GameLogger.LogYellow("resend: " + m_cachePacks[i].proto + ", " + m_cachePacks[i].session); + obj2Stream(m_cachePacks[i].proto, m_cachePacks[i].spObj, m_cachePacks[i].session, out data, out length); + send(m_cachePacks[i].session, m_cachePacks[i].proto, data, length); + } + } + + private void cachePack(string proto, SpObject arg) + { + //if (IgnoreResendMsgDef.isIgnore (proto)) return; + SpObject cacheSpObj = arg == null ? arg : arg.DeepClone(); + m_cachePacks.Add(new CachePackInfo(m_curSession, proto, cacheSpObj)); + } + + private void obj2Stream(string proto, SpObject arg, int session, out byte[] data, out int length) + { + data = null; + length = 0; + m_sendStream.Reset(); + m_sendStream.Write((short)0); + m_rpc.Request(proto, arg, session, m_sendStream); + int len = m_sendStream.Length - 2; + m_sendStream.Buffer[0] = (byte)((len >> 8) & 0xff); + m_sendStream.Buffer[1] = (byte)(len & 0xff); + + // 加密 + // if (m_encrypt != null) + // { + // byte[] out_data; + // int out_data_len = m_encrypt.EncryptProtoBeforeSend(m_sendStream, out out_data); + // data = out_data; + // length = out_data_len; + // return; + // } + + length = m_sendStream.Length; + data = m_sendStream.Buffer; + } + + public void EncryptyData(byte[] src, int srcLen, out byte[] data, out int length) + { + m_sendStream.Reset(); + m_sendStream.Write((short)0); + int len = srcLen; + m_sendStream.Buffer[0] = (byte)((len >> 8) & 0xff); + m_sendStream.Buffer[1] = (byte)(len & 0xff); + m_sendStream.Write(src); + + // 加密 + // if (m_encrypt != null) + // { + // byte[] out_data; + // int out_data_len = m_encrypt.EncryptProtoBeforeSend(m_sendStream, out out_data); + // data = out_data; + // length = out_data_len; + // return; + // } + + length = m_sendStream.Length; + data = m_sendStream.Buffer; + } + + public void Update() + { + invokeListener(); + if (isConnecting())//连接中 + { + if (isConnectTimeout()) + { + GameLogger.LogWarning("connect timeout"); + connectFailed(); + return; + } + + if (isConnectOk()) + { + try + { + beginReceive(); + } + catch (System.Exception ex) + { + GameLogger.LogWarning("beginReceive error," + ex.ToString()); + connectFailed(); + } + } + } + else//消息回调 + { + if (isResending()) + { + if (isResendTimeout()) + { + resendFailed(); + } + else if (isResendOk()) + { + resendSuccess(); + } + } + + if (isTime2GetMessage()) + { + getMessage(); + dispatchMessage(); + } + } + } + + private bool isConnecting() + { + return m_curNetState == NetState.ConnectStart; + } + + private bool isConnectTimeout() + { + m_connectCounter += Time.deltaTime; + return m_connectCounter > 10f;/// 10秒超时 /// + } + + private bool isConnectOk() + { + if (m_socket == null) return false; + return m_socket.Poll(1000, SelectMode.SelectWrite); + } + + private void beginReceive() + { + m_recvOffset = 0; + m_bConnect = true; + m_packQueue.Clear(); + zeroMemory(m_recvBuffer); + m_socket.EndConnect(m_iAsyncResult); + m_socket.BeginReceive(m_recvBuffer, 0, m_recvBuffer.Length, + SocketFlags.None, recvCallbackFunc, this); + + // 加密 + // if (m_encrypt != null) + // { + // byte[] data = m_encrypt.Init(); + // int ret = m_socket.Send(data); + // Debug.Log(" m_socket.Send(data); == " + ret + " "); + // } + + m_lastRecvTick = DateTime.Now.Ticks; + m_lastSendTick = DateTime.Now.Ticks; + m_heartbeat.Start(); + AddNetState(NetState.ConnectSuccess, null); + } + + private void connectFailed() + { + Close(); + GameLogger.Log("connect failed"); + AddNetState(NetState.ConnectFail, null); + } + + private bool isResending() + { + return m_curNetState == NetState.ResendStart; + } + + private bool isResendTimeout() + { + m_resendCounter += Time.deltaTime; + return m_resendCounter >= 15f; //resend timeout + } + + private bool isResendOk() + { + return m_cachePacks.Count == 0; + } + + private void resendSuccess() + { + m_isReconnect = false; + AddNetState(NetState.ResendSuccess, null); + } + + private void resendFailed() + { + Close(); + GameLogger.Log("resend failed"); + AddNetState(NetState.ResendFail, null); + } + + private bool isTime2GetMessage() + { + m_passTime += Time.deltaTime; + return m_passTime >= CMD_QUEUE_CHECK_INTERVAL; + } + + private void getMessage() + { + m_passTime = 0f; + m_packQueue.getCmdListAndClear(m_streamlist); + } + + private void dispatchMessage() + { + for (int i = 0; i < m_streamlist.Count; ++i) + { + if (m_streamlist[i] != null) + { + SpRpcResult result = stream2Obj(m_streamlist[i]); + if (result != null && result.Protocol != null) + { + //if(result.Op == SpRpcOp.Request) + // GameLogger.LogGreen(result.Protocol.Name + ", " + DateTime.Now.ToString()); + if (removeCachePack(result)) + { + //已经被处理过了, 不需要往下传递了 + if (!result.bProcess) + { + onRecvDataFunc(result); + } + + //网络统计 + NetDataAnalysis.RecieveData(result, m_streamlist[i]); + } + } + } + } + + m_streamlist.Clear(); + } + + private SpRpcResult stream2Obj(SpStream stream) + { + SpRpcResult result = null; + try + { + result = m_rpc.Dispatch(stream); + } + catch (Exception exp) + { + GameLogger.LogError("SpRpcResult: " + exp); + GameLogger.LogError("SpRpcResult: " + exp.StackTrace); + } + + return result; + } + + public void Disconnect() + { + Close(); + GameLogger.Log("disconnect."); + AddNetState(NetState.Disconnect, null); + } + + public void Close() + { + lock (m_locker) + { + m_curNetState = NetState.Disconnect; + if (m_heartbeat != null) + { + m_heartbeat.Stop(); + } + if (m_socket == null) return; + + try + { + m_socket.Shutdown(SocketShutdown.Both); + m_socket.Close(); + } + catch (Exception exception) + { + GameLogger.LogWarning("NetSocket.close, exp: " + exception.Message); + } + + GameLogger.LogYellow("close socket"); + m_bConnect = false; + m_connectCounter = 0f; + m_socket = null; + } + } + + private void send(int session, string proto, byte[] data, int length) + { + try + { + if (data == null || length <= 0) return; + s_sendCount += length; + if (m_socket != null) + { + m_lastSendTick = DateTime.Now.Ticks; + m_socket.Send(data, length, SocketFlags.None); + NetDataAnalysis.SendData(proto, data); + } + } + catch (Exception ex) + { + Close(); + GameLogger.LogWarning(string.Format("send error, protoName:{0}, session:{1}, exp:{2} ", proto, session, ex)); + AddNetState(NetState.Error, null); + } + } + + private bool removeCachePack(SpRpcResult ret) + { + if (ret.Op == SpRpcOp.Request) return true; + //if(IgnoreResendMsgDef.isIgnore(ret.Protocol.Name)) + // return true; + + if (ret.Op == SpRpcOp.Response) + { + for (int i = 0; i < m_cachePacks.Count; ++i) + { + if (ret.Session == m_cachePacks[i].session) + { + m_cachePacks.RemoveAt(i); + return true; + } + } + } + + try + { + if (ret.bProcess) + { + //Lua 已经处理 C# 不需要处理 + return true; + } + //lua C#也需要同时处理 + //有些是lua发送的协议, 但是lua 不处理 留个C#处理~ + return true; + //Util.DumpObject(ret.Arg); + } + catch (System.Exception ex) + { + GameLogger.LogError("removeCachePack, " + ex); + } + + return false; + } + + private void recvCallback(IAsyncResult ar) + { + try + { + int len = 0; + lock (m_locker) + { + if (m_socket != null) len = m_socket.EndReceive(ar); + if (len > 0) m_lastRecvTick = DateTime.Now.Ticks; + } + + if (len > 0) + { + s_recvCount += len; + m_recvOffset += len; + m_read = 0; + + while (m_recvOffset - m_read >= 2) + { + int size = 0; + try + { + size = (m_recvBuffer[m_read + 1] | (m_recvBuffer[m_read + 0] << 8)); + if (size > m_recvBuffer.Length) + GameLogger.LogError(string.Format("out of size!!!!!recv data size:{0}", size)); + // if (m_encrypt != null && size % 8 != 0) + // GameLogger.LogError(string.Format("Error size % 8 != 0 size={0}", size)); + } + catch (Exception exp) + { + GameLogger.LogError("out of size: " + exp.Message); + } + + if (m_recvOffset >= (m_read + 2 + size)) + { + SpStream stream; + // if (m_encrypt != null) + // { + // stream = m_encrypt.DecryptAsSpStream(m_recvBuffer, m_read + 2, size); + // } + // else + { + stream = new SpStream(size); + stream.Write(m_recvBuffer, m_read + 2, size); + } + + stream.Position = 0; + m_packQueue.pushCmd(stream); + m_read = m_read + 2 + size; + } + else + { + break; + } + } + + if (m_read > 0) + { + for (int i = m_read; i < m_recvOffset; ++i) + { + m_recvBuffer[i - m_read] = m_recvBuffer[i]; + } + + m_recvOffset -= m_read; + } + + lock (m_locker) + { + if (m_socket != null) + { + m_socket.BeginReceive(m_recvBuffer, m_recvOffset, + m_recvBuffer.Length - m_recvOffset, SocketFlags.None, recvCallbackFunc, this); + } + } + } + } + catch (Exception exception) + { + Close(); + string errMsg = "NetSocket.recvCallback, exp: " + exception.Message; + Debug.LogError(errMsg); + AddNetState(NetState.Error, errMsg); + } + } + + public void AddNetState(NetState state, object param = null) + { + lock (m_locker) + { + m_curNetState = state; + NetStateParam item = new NetStateParam(); + item.netstate = state; + item.param = param; + m_netStateList.Add(item); + } + } + + private void invokeListener() + { + lock (m_locker) + { + if (m_netStateList.Count > 0) + { + foreach (INetStateListener lisenter in m_listeners) + { + if (lisenter != null) + lisenter.OnNetStateChanged(m_netStateList[0].netstate, m_netStateList[0].param); + } + + m_netStateList.RemoveAt(0); + } + } + } + + private void zeroMemory(byte[] buffer) + { + if (buffer != null) + { + for (int i = 0; i < buffer.Length; ++i) + buffer[i] = 0; + } + } + + public int getCachPacksLen() + { + return m_cachePacks.Count; + } + + public void ClearMsgQueue() + { + m_cachePacks.Clear(); + m_packQueue.Clear(); + m_streamlist.Clear(); + } + + public bool enableCrypt + { + get { return m_isEnableCrypt; } + + set + { + m_isEnableCrypt = value; + if (m_isEnableCrypt) + { + if (m_encrypt == null) m_encrypt = new ProtoEncrypt(); + } + else + { + m_encrypt = null; + } + } + } + + public bool isConnect { get { return m_bConnect; } } + public long lastSendTick { get { return m_lastSendTick; } } + public long lastRecvTick { get { return m_lastRecvTick; } } + public static int recvCount { get { return s_recvCount; } } + public static int sendCount { get { return s_sendCount; } } + public int GetNextSession() + { + m_curSession++; + return m_curSession; + } + + private static int s_recvCount = 0; + private static int s_sendCount = 0; + + private int m_read; + private int m_curSession; + private int m_recvOffset; + private bool m_bConnect; + private bool m_isReconnect; + private long m_lastRecvTick; + private long m_lastSendTick; + private object m_locker; + private float m_passTime; + private float m_connectCounter; + private float m_resendCounter; + private byte[] m_recvBuffer; + private SpRpc m_rpc; + private Socket m_socket; + private SpStream m_sendStream; + private ArrayList m_listeners; + private HeartBeat m_heartbeat; + private PackageQueue m_packQueue; + private List m_streamlist; + private NetState m_curNetState; + private OnRecvData onRecvDataFunc; + private IAsyncResult m_iAsyncResult; + private List m_cachePacks; + private AsyncCallback recvCallbackFunc; + private List m_netStateList; + private bool m_isEnableCrypt; + private ProtoEncrypt m_encrypt = null; + private const float CMD_QUEUE_CHECK_INTERVAL = 0.06f; + + + /// + /// 回调参数 + /// + private struct NetStateParam + { + public NetState netstate; + public object param; + } + + private class CachePackInfo + { + public CachePackInfo(int session, string proto, SpObject spObj) + { + this.session = session; + this.proto = proto; + this.spObj = spObj; + } + + public int session; + public string proto; + public SpObject spObj; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Framework/Network/RemoteConnection.cs.meta b/Assets/Scripts/Framework/Network/RemoteConnection.cs.meta new file mode 100644 index 0000000..227ebc6 --- /dev/null +++ b/Assets/Scripts/Framework/Network/RemoteConnection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7dcba09ae929f044bf5fb4269242665 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Network/SocketPackageQueue.cs b/Assets/Scripts/Framework/Network/SocketPackageQueue.cs new file mode 100644 index 0000000..ebaa53c --- /dev/null +++ b/Assets/Scripts/Framework/Network/SocketPackageQueue.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; + +/// +/// Socket包队列 +/// +public class PackageQueue +{ + public PackageQueue() + { + @_cmdList = new List(); + } + + public void pushCmd(SpStream result) + { + lock (@_dataLocker) + { + @_cmdList.Add(result); + } + } + + public void getCmdListAndClear(List ret) + { + lock (@_dataLocker) + { + if (@_cmdList.Count > 0) + { + for (int i = 0; i < @_cmdList.Count; ++i) + { + ret.Add(@_cmdList[i]); + } + + @_cmdList.Clear(); + } + } + } + + public void Clear() + { + lock (@_dataLocker) + { + @_cmdList.Clear(); + } + } + + private List @_cmdList; + + private byte[] @_dataLocker = new byte[0]; +} diff --git a/Assets/Scripts/Framework/Network/SocketPackageQueue.cs.meta b/Assets/Scripts/Framework/Network/SocketPackageQueue.cs.meta new file mode 100644 index 0000000..d319963 --- /dev/null +++ b/Assets/Scripts/Framework/Network/SocketPackageQueue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37e616dd274e3554f9d3cd3de88bd366 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Panel/BasePanel.cs b/Assets/Scripts/Framework/Panel/BasePanel.cs index 7be16b1..8e466eb 100644 --- a/Assets/Scripts/Framework/Panel/BasePanel.cs +++ b/Assets/Scripts/Framework/Panel/BasePanel.cs @@ -8,54 +8,92 @@ using LuaInterface; public class BasePanel : MonoBehaviour { - private LuaFunction onShow; - private LuaFunction onHide; - private LuaFunction onUpdate; - private LuaFunction onRegistEvent; - private LuaFunction onUnRegistEvent; - private string panelName; - public GameObject panelObj { get; private set; } - - public void Initialize(string panelName, GameObject panelObj) - { - this.panelName = panelName; - this.panelObj = panelObj; - LuaManager luaMgr = LuaHelper.GetLuaManager(); - if (null != luaMgr) - { - onShow = luaMgr.GetFunction(panelName + ".OnShow", false); - onHide = luaMgr.GetFunction(panelName + ".OnHide", false); - onUpdate = luaMgr.GetFunction(panelName + ".OnUpdate", false); - onRegistEvent = luaMgr.GetFunction(panelName + ".RegistEvent", false); - onUnRegistEvent = luaMgr.GetFunction(panelName + ".UnRegistEvent", false); - } - } - - public void Show() - { - if (null != onShow) - { - onShow.Call(panelObj); - if (onRegistEvent != null) - onRegistEvent.Call(); - } - } - - public void Hide() - { - Destroy(panelObj); - Util.ClearMemory(); - if (null != onHide) - { - onHide.Call(); - if (onUnRegistEvent != null) - onUnRegistEvent.Call(); - } - } - - private void Update() - { - if (null != onUpdate) - onUpdate.Call(); + // 状态,0:未显示,1:显示 + private int mState = 0; + private LuaInterface.LuaTable mLuaObj; + private GameObject mSelfObj; + private Transform mSelfTrans; + private LuaFunction luaFuncOnShow; + private LuaFunction luaFuncOnHide; + private LuaFunction luaFuncUpdate; + private LuaFunction luaFuncRegistEvent; + private LuaFunction luaFuncUnRegistEvent; + + /// + /// Lua写的Panel脚本由BasePanel来调度,通过luaObj来绑定调度的方法 + /// + /// Lua Panel的对象 + public void LuaBind(LuaInterface.LuaTable luaObj) + { + mLuaObj = luaObj; + luaFuncOnShow = luaObj.GetLuaFunction("OnShow"); + luaFuncOnHide = luaObj.GetLuaFunction("OnHide"); + luaFuncUpdate = luaObj.GetLuaFunction("Update"); + luaFuncRegistEvent = luaObj.GetLuaFunction("RegistEvent"); + luaFuncUnRegistEvent = luaObj.GetLuaFunction("UnRegistEvent"); + } + + protected virtual void Awake() + { + mSelfObj = gameObject; + mSelfTrans = transform; + } + + protected virtual void Start() + { + + } + + protected virtual void Update() + { + if (null != luaFuncUpdate) + luaFuncUpdate.Call(mLuaObj); + } + + public virtual void Show() + { + if (1 == mState) + return; + mState = 1; + mSelfObj.SetActive(true); + + OnShow(mSelfTrans); + RegistEvent(); + } + + protected virtual void OnShow(Transform parent) + { + if (null != luaFuncOnShow) + luaFuncOnShow.Call(mLuaObj, parent); + } + + protected virtual void RegistEvent() + { + if (null != luaFuncRegistEvent) + luaFuncRegistEvent.Call(mLuaObj); + } + + public virtual void Hide() + { + if (0 == mState) + return; + + OnHide(); + UnRegistEvent(); + + mSelfObj.SetActive(false); + mState = 0; + } + + protected virtual void OnHide() + { + if (null != luaFuncOnHide) + luaFuncOnHide.Call(mLuaObj); + } + + protected virtual void UnRegistEvent() + { + if (null != luaFuncUnRegistEvent) + luaFuncUnRegistEvent.Call(mLuaObj); } } diff --git a/Assets/Scripts/Framework/Panel/PanelMgr.cs b/Assets/Scripts/Framework/Panel/PanelMgr.cs index c61d79b..027e221 100644 --- a/Assets/Scripts/Framework/Panel/PanelMgr.cs +++ b/Assets/Scripts/Framework/Panel/PanelMgr.cs @@ -1,8 +1,9 @@ -using System.Collections; using System.Collections.Generic; using UnityEngine; -using UnityEngine.UI; +/// +/// 界面管理器 +/// public class PanelMgr { private static PanelMgr mInstance; @@ -20,71 +21,81 @@ public class PanelMgr private Transform mRootCanvas; // 界面管理仓库 - private Dictionary mPanels = new Dictionary(); + private Dictionary mPanels = new Dictionary(); public void Init() { mRootCanvas = GameObject.Find("Canvas").transform; } + public BasePanel GetPanelById(int panelId) + { + BasePanel panel = null; + mPanels.TryGetValue(panelId, out panel); + return panel; + } + /// - /// 展示界面 + /// 显示界面(供Lua层调用) /// - /// 界面名称 - /// 资源id + /// 界面Id + /// Lua界面脚本对象,是一个LuaTable + /// 父节点 /// - public BasePanel ShowPanel(string panelName, int resId) + public BasePanel ShowPanel(int panelId, LuaInterface.LuaTable luaObj, Transform parent) { - if (null != panelName && mPanels.ContainsKey(panelName)) - return mPanels[panelName]; - var resCfg = ResourceCfg.instance.GetResCfg(resId); - if (null != resCfg) + var panel = GetPanelById(panelId); + if (null == panel) { - return ShowPanel(panelName, resCfg.editor_path); + var go = new GameObject(luaObj.GetStringField("panelName")); + go.transform.SetParent(parent, false); + var rectTrans = go.AddComponent(); + rectTrans.anchorMin = Vector2.zero; + rectTrans.anchorMax = Vector2.one; + rectTrans.offsetMin = Vector2.zero; + rectTrans.offsetMax = Vector2.zero; + panel.gameObject.AddComponent(); + panel.LuaBind(luaObj); + mPanels.Add(panelId, panel); } - else - { - GameLogger.LogError("ShowPanel Error, null == resCfg, resId = " + resId); - return null; - } - } - - public T ShowPanel(string panelName, string resPath) where T : BasePanel - { - if (null != panelName && mPanels.ContainsKey(panelName)) - return mPanels[panelName] as T; - var prefab = ResourceMgr.instance.LoadAsset(resPath); - var go = Object.Instantiate(prefab); - go.transform.SetParent(mRootCanvas, false); - var panel = go.GetOrAddComponent(); - panel.Initialize(panelName, go); - if (null != panelName) - mPanels.Add(panelName, panel); panel.Show(); return panel; } - public GameObject InstantiateUI(int resId) + /// + /// 显示界面(供C#层调用) + /// + /// 界面名称 + /// 资源id + /// + public T ShowPanel(int panelId, Transform parent) where T : BasePanel { - var resCfg = ResourceCfg.instance.GetResCfg(resId); - if (null == resCfg) + var panel = GetPanelById(panelId); + if (null == panel) { - return null; + var go = new GameObject(typeof(T).ToString()); + go.transform.SetParent(parent, false); + var rectTrans = go.AddComponent(); + rectTrans.anchorMin = Vector2.zero; + rectTrans.anchorMax = Vector2.one; + rectTrans.offsetMin = Vector2.zero; + rectTrans.offsetMax = Vector2.zero; + panel = go.AddComponent(); + mPanels.Add(panelId, panel); } - var prefab = ResourceMgr.instance.LoadAsset(resCfg.editor_path); - if (null == prefab) - return null; - var uiObj = Object.Instantiate(prefab); - uiObj.transform.SetParent(mRootCanvas, false); - return uiObj; + panel.Show(); + return (T)panel; } - public void HidePanel(string panelName) + + /// + /// 关闭界面 + /// + /// 界面ID + public void HidePanel(int panelId) { - if (mPanels.ContainsKey(panelName)) - { - mPanels[panelName].Hide(); - mPanels.Remove(panelName); - } + var panel = GetPanelById(panelId); + if (null != panel) + panel.Hide(); } public void HideAllPanels() @@ -93,6 +104,5 @@ public class PanelMgr { panel.Hide(); } - mPanels.Clear(); } } diff --git a/Assets/Scripts/Framework/Prefab/PrefabObjBinder.cs b/Assets/Scripts/Framework/Prefab/PrefabObjBinder.cs index 3f13c97..7c14136 100644 --- a/Assets/Scripts/Framework/Prefab/PrefabObjBinder.cs +++ b/Assets/Scripts/Framework/Prefab/PrefabObjBinder.cs @@ -4,6 +4,9 @@ using System.Collections; using System.Collections.Generic; using System; +/// +/// 预设物体绑定器 +/// public class PrefabObjBinder : MonoBehaviour { [System.Serializable] diff --git a/Assets/Scripts/Framework/Resource/AssetBundleMgr.cs b/Assets/Scripts/Framework/Resource/AssetBundleMgr.cs new file mode 100644 index 0000000..a942704 --- /dev/null +++ b/Assets/Scripts/Framework/Resource/AssetBundleMgr.cs @@ -0,0 +1,189 @@ +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using UnityEditor; + +/// +/// assetbundle管理 +/// +public class AssetBundleMgr +{ + private static AssetBundleMgr mInstance; + public static AssetBundleMgr instance + { + get + { + if (null == mInstance) + mInstance = new AssetBundleMgr(); + return mInstance; + } + } + + // assetbundle管理仓库 + private Dictionary mBundles; + // assets管理仓库 + private Dictionary mAssets; + // 常规配置assetbundle(C#使用的xml配置表) + public AssetBundle mNormalCfgBundle; + + /// + /// 热更新目录 + /// + /// + public string updatePath + { + get + { + return Application.persistentDataPath + "/update"; + } + } + + /// + /// 拓展包资源目录 + /// + /// + public string extPath + { + get + { + return Application.persistentDataPath + "/ext/"; + } + } + + /// + /// 内部资源目录 + /// 获取内部资源路径,对应streamingAssetsPath + /// 一般情况,streamingAssetsPath目录中的资源只能用WWW异步加载,但是AssetBundle提供了LoadFromFile方法可以直接同步加载 + /// 在Android中,Application.streamingAssetsPath会在前面加上"jar:file://" + /// 所以不直接使用Application.streamingAssetsPath,而使用Application.dataPath + "!assets" + /// + /// + public string internalPath + { + get + { +#if UNITY_ANDROID + return Application.dataPath + "!assets/res/"; +#else + return Application.streamingAssetsPath + "/res/"; +#endif + } + } + + public AssetBundleMgr() + { + mBundles = new Dictionary(); + mAssets = new Dictionary(); + } + + /// + /// 预加载assetbundle资源 + /// + public void PreloadAssetBundles() + { +#if UNITY_EDITOR + // Nothing +#else + mNormalCfgBundle = LoadAssetBundle("normalCfg.bundle"); +#endif + } + + public Object LoadAsset(string resPath) + { + System.Type t = GetAssetType(resPath); + if (mAssets.ContainsKey(resPath)) + return mAssets[resPath]; + + Object obj = null; +#if UNITY_EDITOR + obj = AssetDatabase.LoadAssetAtPath("Assets/GameRes/" + resPath, t); +#else + // resouces.bytes的第一级目录为AssetBundle + var abName = resPath.Substring(0, resPath.IndexOf("/")).ToLower() + ".bundle"; + var fname = Path.GetFileName(resPath); + AssetBundle ab = null; + if (File.Exists(updatePath + "/" + fname)) + { + // 热更的资源,是一个独立的assetbundle文件,已fname为文件名 + ab = LoadAssetBundle(fname); + } + else + { + ab = LoadAssetBundle(abName); + } + if (null != ab) + { + var assetName = fname.Substring(0, fname.IndexOf(".")); + obj = ab.LoadAsset(assetName); + } +#endif + if (null != obj) + { + mAssets[resPath] = obj; + } + return obj; + } + + /// + /// 根据指定路径获取文件类型 + /// + /// + /// + protected System.Type GetAssetType(string resPath) + { + if (resPath.EndsWith(".prefab")) + { + return typeof(GameObject); + } + return typeof(AssetBundle); + } + + /// + /// 读取AssetBundle + /// + /// 名称 + /// + public AssetBundle LoadAssetBundle(string abName) + { + if (mBundles.ContainsKey(abName)) + return mBundles[abName]; + + AssetBundle bundle = null; + if (File.Exists(updatePath + "/" + abName)) + { + // 优先从update目录(热更新目录)中查找资源 + bundle = AssetBundle.LoadFromFile(updatePath + "/" + abName); + } + else if (File.Exists(extPath + "/" + abName)) + { + // 从拓展包目录加载资源 + bundle = AssetBundle.LoadFromFile(extPath + "/" + abName); + } + else + { + bundle = AssetBundle.LoadFromFile(internalPath + abName); + } + + if (null != bundle) + { + mBundles[abName] = bundle; + GameLogger.Log("LoadAssetBundle Ok, abName: " + abName); + } + return bundle; + } + + /// + /// 获取AssetBundle + /// + /// + /// + public AssetBundle GetAssetBundle(string abName) + { + if (mBundles.ContainsKey(abName)) + { + return mBundles[abName]; + } + Debug.LogError("GetAssetBundle Error, not contains: " + abName); + return null; + } +} diff --git a/Assets/Scripts/Framework/Resource/AssetBundleMgr.cs.meta b/Assets/Scripts/Framework/Resource/AssetBundleMgr.cs.meta new file mode 100644 index 0000000..a6458c6 --- /dev/null +++ b/Assets/Scripts/Framework/Resource/AssetBundleMgr.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: edcc56fb48ad3aa4da6cd4ca83bd883a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Resource/ConfigItem.cs b/Assets/Scripts/Framework/Resource/ConfigItem.cs new file mode 100644 index 0000000..7701b6c --- /dev/null +++ b/Assets/Scripts/Framework/Resource/ConfigItem.cs @@ -0,0 +1,108 @@ +using UnityEngine; +using System.Xml; +using System.Collections.Generic; +using System; + +/// +/// 配置Item类 +/// +public interface IConfigItem +{ + string GetKey(); + bool Parse(XmlNode node); +} + +public abstract class ConfigItem +{ + public const string KeySpan = "_"; + public abstract string GetKey(); + + public virtual void OnItemParsed() + { + + } + + public virtual bool Parse(XmlNode node) + { + object self = this; + var result = ObjectParser.Parse(node, ref self, this.GetType()); + + OnItemParsed(); + + return result == ObjectParser.Result.OK; + } +} + +public class ConfigFile where T : ConfigItem +{ + protected Dictionary m_items = new Dictionary(); + + public ConfigFile(string filePath) + { + XmlDocument doc = null; + doc = XMLUtil.GetEssentialXmlCfg(filePath); + if(null == doc) + { + GameLogger.LogError("Read Cfg Error, null == doc, path: " + filePath); + } + + if (!InitFile(doc)) + { + GameLogger.LogError("Init Config File Error filePath = " + filePath); + } + } + + public bool InitFile(XmlDocument doc) + { + XmlNodeList nodeList = doc.GetElementsByTagName("item"); + string errorStr = ""; + int count = nodeList.Count; + for (int i = 0; i < count; i++) + { + + XmlNode node = nodeList[i]; + T obj = (T)Activator.CreateInstance(typeof(T));//ReflectionUtils.CreateInstance(typeof(T)); + if (!obj.Parse(node)) + { + errorStr += ObjectParser.lastError; + } + var key = obj.GetKey(); + if (!m_items.ContainsKey(key)) + m_items.Add(key, obj); + else + GameLogger.LogError(string.Format("cfg has contains the same key,key:{0}", key)); + + } + + if (!string.IsNullOrEmpty(errorStr)) + { + Debug.LogError("InitFile error " + errorStr); + return false; + } + else if (count == 0) + { + string baseUrl = doc.BaseURI; + int index = baseUrl.LastIndexOf('/'); + baseUrl = baseUrl.Substring(index + 1); + Debug.LogError("Cannot find Elements item, file name = " + baseUrl); + return false; + } + else + { + return true; + } + } + + public T GetItem(string key) + { + T item = null; + m_items.TryGetValue(key, out item); + + return item; + } + + public Dictionary GetAllItems() + { + return m_items; + } +} diff --git a/Assets/Scripts/Framework/Resource/ConfigItem.cs.meta b/Assets/Scripts/Framework/Resource/ConfigItem.cs.meta new file mode 100644 index 0000000..a7dffc6 --- /dev/null +++ b/Assets/Scripts/Framework/Resource/ConfigItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47a42d673153b84439221d4a39a6774f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Resource/ResourceCfg.cs b/Assets/Scripts/Framework/Resource/ResourceCfg.cs deleted file mode 100644 index f211fdb..0000000 --- a/Assets/Scripts/Framework/Resource/ResourceCfg.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using LitJson; - -public class ResourceCfg -{ - private static ResourceCfg mInstance; - public static ResourceCfg instance - { - get - { - if (null == mInstance) - mInstance = new ResourceCfg(); - return mInstance; - } - } - - private Dictionary mResCfg = new Dictionary(); - - public void LoadCfg() - { - var text = ResourceMgr.instance.LoadCfgFile("resources.bytes"); - var list = JsonMapper.ToObject>(text); - for (int i = 0; i < list.Count; i++) - { - var item = list[i]; - if (!mResCfg.ContainsKey(item.id)) - { - mResCfg.Add(item.id, item); - } - else - { - GameLogger.LogError("resources.bytes 有资源id重复,id:" + item.id); - } - } - } - - public ResourceCfgItem GetResCfg(int resId) - { - if (mResCfg.ContainsKey(resId)) - return mResCfg[resId]; - GameLogger.LogError("ResourceCfg.GetResCfg Error, resId = " + resId); - return null; - } -} - -public class ResourceCfgItem -{ - public int id; - public string editor_path; -} \ No newline at end of file diff --git a/Assets/Scripts/Framework/Resource/ResourceCfg.cs.meta b/Assets/Scripts/Framework/Resource/ResourceCfg.cs.meta deleted file mode 100644 index 8a687a2..0000000 --- a/Assets/Scripts/Framework/Resource/ResourceCfg.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 90495931b9e1bf3438d3441882233c90 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/Framework/Resource/ResourceConfigItem.cs b/Assets/Scripts/Framework/Resource/ResourceConfigItem.cs new file mode 100644 index 0000000..977e3a6 --- /dev/null +++ b/Assets/Scripts/Framework/Resource/ResourceConfigItem.cs @@ -0,0 +1,39 @@ +/// +/// 资源配置item +/// +public class ResourceConfigItem : ConfigItem +{ + public int id; + public string editorPath; + public string desc; + public string name; + + public override string GetKey() + { + return id.ToString(); + } + + public override void OnItemParsed() + { + parseName(); + } + + private void parseName() + { + int index0 = editorPath.LastIndexOf("."); + int index1 = editorPath.LastIndexOf("/"); + if (index0 == -1 && index1 != -1) + { + name = editorPath.Substring(index1 + 1, editorPath.Length - index1 - 1); + } + else + { + name = editorPath.Substring(index1 + 1, index0 - index1 - 1); + } + } + + public override string ToString() + { + return string.Format("id = {0},path = {1},description = {2}", id, editorPath, desc); + } +} diff --git a/Assets/Scripts/Framework/Resource/ResourceConfigItem.cs.meta b/Assets/Scripts/Framework/Resource/ResourceConfigItem.cs.meta new file mode 100644 index 0000000..1577422 --- /dev/null +++ b/Assets/Scripts/Framework/Resource/ResourceConfigItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88a8cb1797b128844b5880c011711863 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/Resource/ResourceMgr.cs b/Assets/Scripts/Framework/Resource/ResourceMgr.cs index 370477e..0056847 100644 --- a/Assets/Scripts/Framework/Resource/ResourceMgr.cs +++ b/Assets/Scripts/Framework/Resource/ResourceMgr.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using System.IO; using UnityEngine; -using UnityEditor; +/// +/// 资源管理器 +/// public class ResourceMgr { private static ResourceMgr mInstance; @@ -16,141 +18,90 @@ public class ResourceMgr } } - // assetbundle管理仓库 - private Dictionary mBundles = new Dictionary(); - // assets管理仓库 - private Dictionary mAssets = new Dictionary(); + private ConfigFile mResourceConfigFile; + private Dictionary mResPathDic; - public string updatePath + public ResourceMgr() { - get + mResPathDic = new Dictionary(); + } + + public void Init() + { + mResourceConfigFile = new ConfigFile("resources"); + Dictionary allItems = mResourceConfigFile.GetAllItems(); + foreach (KeyValuePair p in allItems) { - return Application.persistentDataPath + "/update"; + if (!mResPathDic.ContainsKey(p.Value.editorPath)) + { + mResPathDic.Add(p.Value.editorPath, p.Value); + } + else + { + GameLogger.Log("name not be same, " + p.Value.editorPath); + } } } - /// - /// 预加载基础的bundle资源 - /// - public void PreloadBaseBundle() + public ResourceConfigItem GetResourceItem(int resId) { - LoadAssetBundle("baseres.bundle"); + ResourceConfigItem item = mResourceConfigFile.GetItem(resId.ToString()); + if (item == null) + { + GameLogger.LogError("getResourceItem error, not contain id: " + resId); + } + return item; } - /// - /// 预加载lua的bundle资源 - /// - public void PreloadLuaBundles() + public ResourceConfigItem GetResourceItem(string resPath) { - if (File.Exists(updatePath + "/lua_update.bundle")) - LoadAssetBundle("lua_update.bundle"); - LoadAssetBundle("lua.bundle"); + if (mResPathDic.ContainsKey(resPath)) + { + return mResPathDic[resPath]; + } + return null; } - public T LoadAsset(int resId) where T : UnityEngine.Object + public T Instantiate(int resId) where T : Object { - var resCfg = ResourceCfg.instance.GetResCfg(resId); - return LoadAsset(resCfg.editor_path); + return Instantiate(ResId2ResPath(resId)); } - public T LoadAsset(string resPath) where T : UnityEngine.Object + public T Instantiate(string resPath) where T : Object { - if (mAssets.ContainsKey(resPath)) - return mAssets[resPath] as T; - - T obj = null; -#if UNITY_EDITOR - obj = AssetDatabase.LoadAssetAtPath("Assets/GameRes/" + resPath); -#else - var abName = resPath.Substring(0, resPath.IndexOf("/")).ToLower() + ".bundle"; - var fname = Path.GetFileName(resPath); - AssetBundle ab = null; - if (File.Exists(updatePath + "/" + fname)) - { - // 热更的资源,是一个独立的assetbundle文件,已fname为文件名 - ab = LoadAssetBundle(fname); - } - else + var obj = AssetBundleMgr.instance.LoadAsset(resPath); + if (null == obj) { - ab = LoadAssetBundle(abName); + GameLogger.LogError("Instantiate Error, resPath:" + resPath); + return default(T); } - if (null != ab) + if (typeof(T) == typeof(GameObject)) { - var assetName = fname.Substring(0, fname.IndexOf(".")); - obj = ab.LoadAsset(assetName); - } -#endif - if (null != obj) - mAssets[resPath] = obj; - return obj; - } - - /// - /// 读取配置文件 - /// - /// - /// - public string LoadCfgFile(string cfgFileName) - { - TextAsset asset = null; -#if UNITY_EDITOR - asset = AssetDatabase.LoadAssetAtPath("Assets/GameRes/Config/" + cfgFileName); -#else - var bundle = LoadAssetBundle("normal_cfg.bundle"); - if (null != bundle) - asset = bundle.LoadAsset(cfgFileName); -#endif - if (null != asset) - { - return asset.text; + T go = Object.Instantiate(obj) as T; + return go; } else { - GameLogger.LogError("ResourceMgr.LoadCfgFile Error, asset = null, cfgFileName = " + cfgFileName); - return null; + return obj as T; } } - /// - /// 读取AssetBundle - /// - /// 名称 - /// - private AssetBundle LoadAssetBundle(string abName) + private string ResId2ResPath(int resId) { - if (mBundles.ContainsKey(abName)) - return mBundles[abName]; - - AssetBundle bundle = null; - if (File.Exists(updatePath + "/" + abName)) + ResourceConfigItem item = GetResourceItem(resId); + if (item == null) { - // 优先从update目录(热更新目录)中查找资源 - bundle = AssetBundle.LoadFromFile(updatePath + "/" + abName); + return string.Empty; } - else - { - bundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/res/" + abName); - } - - if (null != bundle) - { - mBundles[abName] = bundle; - } - return bundle; + return item.editorPath; } - /// - /// 获取AssetBundle - /// - /// - /// - public AssetBundle GetAssetBundle(string abName) + public int ResPath2ResId(string url) { - if (mBundles.ContainsKey(abName)) + if (mResPathDic.ContainsKey(url)) { - return mBundles[abName]; + return mResPathDic[url].id; } - Debug.LogError("GetAssetBundle Error, not contains: " + abName); - return null; + return -1; } } diff --git a/Assets/Scripts/Framework/Resource/ResourceMgr.cs.meta b/Assets/Scripts/Framework/Resource/ResourceMgr.cs.meta index 31e285d..11dff05 100644 --- a/Assets/Scripts/Framework/Resource/ResourceMgr.cs.meta +++ b/Assets/Scripts/Framework/Resource/ResourceMgr.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f25fcd1d9f9c56c49ad57da55e009ede +guid: 98373f79fdb1a514c976e66fb8793e72 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/Framework/Resource/ResourcePathBuilder.cs b/Assets/Scripts/Framework/Resource/ResourcePathBuilder.cs new file mode 100644 index 0000000..d2a93bd --- /dev/null +++ b/Assets/Scripts/Framework/Resource/ResourcePathBuilder.cs @@ -0,0 +1,38 @@ +using UnityEngine; + +/// +/// 资源路径管理 +/// +public class ResourcePathBuilder +{ + static ResourcePathBuilder() + { + } + + public static string BuildConfigPath(string name) + { +#if UNITY_EDITOR + string path = "Assets/GameRes/Config/" + name; + if (!path.EndsWith(".bytes")) path += ".bytes"; + return path; +#else + return name; +#endif + } + + public static string buildUnityEditorPath(string path) + { + return "Res/" + path; + } + + public static string GetStreamingUrl(string name) + { +#if UNITY_IPHONE || UNITY_EDITOR + string url = string.Format("file://{0}/{1}", Application.streamingAssetsPath, name); +#else + string url = Application.streamingAssetsPath + "/"+ name; +#endif + + return url; + } +} diff --git a/Assets/Scripts/Framework/Resource/ResourcePathBuilder.cs.meta b/Assets/Scripts/Framework/Resource/ResourcePathBuilder.cs.meta new file mode 100644 index 0000000..c99bfcd --- /dev/null +++ b/Assets/Scripts/Framework/Resource/ResourcePathBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e65bdaf3108eb74aa8019652f8201cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/SprotoDef.meta b/Assets/Scripts/Framework/SprotoDef.meta new file mode 100644 index 0000000..3aa20fd --- /dev/null +++ b/Assets/Scripts/Framework/SprotoDef.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: aa3bb931c3a4905438060ebf31ebf232 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Framework/SprotoDef/c2s.cs b/Assets/Scripts/Framework/SprotoDef/c2s.cs new file mode 100644 index 0000000..72d79b4 --- /dev/null +++ b/Assets/Scripts/Framework/SprotoDef/c2s.cs @@ -0,0 +1,21 @@ +///This code was generated by menu [Tools/sproto2cs], DO NOT EDIT! + +public class c2s { + public const string sproto = @" +.package { + type 0 : integer + session 1 : integer +} + + +sayhello 1 { + request { + what 0 : string + } + response { + error_code 0 : integer + msg 1 : string + } +} +"; +} \ No newline at end of file diff --git a/Assets/LuaFramework/Scripts/Common/LuaLoader.cs.meta b/Assets/Scripts/Framework/SprotoDef/c2s.cs.meta similarity index 75% rename from Assets/LuaFramework/Scripts/Common/LuaLoader.cs.meta rename to Assets/Scripts/Framework/SprotoDef/c2s.cs.meta index fc3badd..42d22bf 100644 --- a/Assets/LuaFramework/Scripts/Common/LuaLoader.cs.meta +++ b/Assets/Scripts/Framework/SprotoDef/c2s.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 317fe630a9afeed49987f352e46b52af -timeCreated: 1453126595 +guid: e2a2966d74873df4787ab728fb111cc0 +timeCreated: 1494818763 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/Assets/Scripts/Framework/SprotoDef/s2c.cs b/Assets/Scripts/Framework/SprotoDef/s2c.cs new file mode 100644 index 0000000..7e24da6 --- /dev/null +++ b/Assets/Scripts/Framework/SprotoDef/s2c.cs @@ -0,0 +1,14 @@ +///This code was generated by menu [Tools/sproto2cs], DO NOT EDIT! + +public class s2c { + public const string sproto = @" +.package { + type 0 : integer + session 1 : integer +} + + +heartbeat 1 {} + +"; +} \ No newline at end of file diff --git a/Assets/LuaFramework/Scripts/View/AppView.cs.meta b/Assets/Scripts/Framework/SprotoDef/s2c.cs.meta similarity index 75% rename from Assets/LuaFramework/Scripts/View/AppView.cs.meta rename to Assets/Scripts/Framework/SprotoDef/s2c.cs.meta index 07f824c..bd739e5 100644 --- a/Assets/LuaFramework/Scripts/View/AppView.cs.meta +++ b/Assets/Scripts/Framework/SprotoDef/s2c.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 354aa74efb1b7424f9b142bc0073df53 -timeCreated: 1440243752 +guid: 9466aa9fc1c6e1a429ffd0fe98b04339 +timeCreated: 1494818958 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/Assets/Scripts/Framework/sproto.meta b/Assets/Scripts/Framework/sproto.meta new file mode 100644 index 0000000..e905104 --- /dev/null +++ b/Assets/Scripts/Framework/sproto.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dc77f86666cb79e46b6b6551ec0947f7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LuaFramework/Luajit/jit/dis_mips.lua.meta b/Assets/Scripts/Framework/sproto/src.meta similarity index 56% rename from Assets/LuaFramework/Luajit/jit/dis_mips.lua.meta rename to Assets/Scripts/Framework/sproto/src.meta index 594d9ba..0027755 100644 --- a/Assets/LuaFramework/Luajit/jit/dis_mips.lua.meta +++ b/Assets/Scripts/Framework/sproto/src.meta @@ -1,4 +1,4 @@ fileFormatVersion: 2 -guid: 6d6b0da48d262af4b902b41b630d7c55 +guid: d5cf06c432b2f584ab5918ec62b29fad DefaultImporter: userData: diff --git a/Assets/Scripts/Framework/sproto/src/SpCodec.cs b/Assets/Scripts/Framework/sproto/src/SpCodec.cs new file mode 100644 index 0000000..3d0b6ad --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpCodec.cs @@ -0,0 +1,478 @@ +using System.Collections.Generic; +using System.IO; +using System; +using System.Text; + +public class SpCodec { + public const int MAX_SIZE = 1000000; + + //private SpStream mStream; + private SpTypeManager mTypeManager; + + public SpCodec (SpTypeManager m) { + mTypeManager = m; + } + + public SpStream Encode (string proto, SpObject obj) { + return Encode (mTypeManager.GetType (proto), obj); + } + + public bool Encode (string proto, SpObject obj, byte[] buffer) { + return Encode (proto, obj, buffer, 0, buffer.Length); + } + + public bool Encode (string proto, SpObject obj, byte[] buffer, int offset, int size) { + return Encode (proto, obj, new SpStream (buffer, offset, size)); + } + + public bool Encode (string proto, SpObject obj, SpStream stream) { + return Encode (mTypeManager.GetType (proto), obj, stream); + } + + public SpStream Encode (SpType type, SpObject obj) { + SpStream stream = new SpStream (); + + if (Encode (type, obj, stream) == false) { + if (stream.IsOverflow ()) { + if (stream.Position > MAX_SIZE) + return null; + + int size = stream.Position; + size = ((size + 7) / 8) * 8; + stream = new SpStream (size); + if (Encode (type, obj, stream) == false) + return null; + } + else { + return null; + } + } + + return stream; + } + + public bool Encode (SpType type, SpObject obj, SpStream stream) { + if (type == null || obj == null || stream == null) + return false; + + //mStream = stream; + bool success = EncodeInternal(type, obj, stream); + return (success && stream.IsOverflow () == false); + } + + private bool EncodeInternal (SpType type, SpObject obj, SpStream mStream) { + if (mStream == null || type == null || obj == null) + return false; + + // buildin type decoding should not be here + if (mTypeManager.IsBuildinType (type)) + return false; + + int begin = mStream.Position; + + // fn. will be update later + short fn = 0; + mStream.Write (fn); + + List> objs = new List> (); + int current_tag = -1; + if (type.Fields != null) + foreach (SpField f in type.Fields) { + if (f == null) + continue; + + SpObject o = obj[f.Name]; + if (o == null || IsTypeMatch (f, o) == false) + continue; + + if (f.Tag <= current_tag) + return false; + + if (f.Tag - current_tag > 1) { + mStream.Write ((short)(2 * (f.Tag - current_tag - 1) - 1)); + fn++; + } + + bool standalone = true; + if (f.IsArray == false) { + if (f.Type == mTypeManager.Boolean) { + int value = o.AsBoolean () ? 1 : 0; + mStream.Write ((short)((value + 1) * 2)); + standalone = false; + } + else if (f.Type == mTypeManager.Integer && o.IsInt()) { + int value = o.AsInt (); + if (value >= 0 && value < 0x7fff) { + mStream.Write ((short)((value + 1) * 2)); + standalone = false; + } + } + } + + if (standalone) { + objs.Add (new KeyValuePair (o, f.Type)); + mStream.Write ((short)0); + } + + fn++; + current_tag = f.Tag; + } + + foreach (KeyValuePair entry in objs) { + if (entry.Key.IsArray ()) { + int array_begin = mStream.Position; + int size = 0; + mStream.Write (size); + + if (entry.Value == mTypeManager.Integer) { + byte len = 4; + foreach (SpObject o in entry.Key.AsArray ()) { + if (o.IsLong ()) { + len = 8; + break; + } + } + + mStream.Write (len); + foreach (SpObject o in entry.Key.AsArray ()) { + if (len == 4) { + mStream.Write (o.AsInt ()); + } + else { + mStream.Write (o.AsLong ()); + } + } + } + else if (entry.Value == mTypeManager.Boolean) { + foreach (SpObject o in entry.Key.AsArray ()) { + mStream.Write ((byte)(o.AsBoolean () ? 1 : 0)); + } + } + else if (entry.Value == mTypeManager.String) { + foreach (SpObject o in entry.Key.AsArray ()) { + if (o.IsBytes()) { + byte[] b = o.AsBytes(); + mStream.Write(b.Length); + mStream.Write(b); + } + else { + byte[] b = Encoding.UTF8.GetBytes(o.AsString()); + mStream.Write(b.Length); + mStream.Write(b); + } + } + } + else { + foreach (SpObject o in entry.Key.AsArray ()) { + int obj_begin = mStream.Position; + int obj_size = 0; + mStream.Write (obj_size); + + if (EncodeInternal (entry.Value, o, mStream) == false) + return false; + + int obj_end = mStream.Position; + obj_size = (int)(obj_end - obj_begin - 4); + mStream.Position = obj_begin; + mStream.Write (obj_size); + mStream.Position = obj_end; + } + } + + int array_end = mStream.Position; + size = (int)(array_end - array_begin - 4); + mStream.Position = array_begin; + mStream.Write (size); + mStream.Position = array_end; + } + else { + if (entry.Key.IsBytes()) { + byte[] b = entry.Key.AsBytes(); + mStream.Write(b.Length); + mStream.Write(b); + } + else if (entry.Key.IsString ()) { + try + { + byte[] b = Encoding.UTF8.GetBytes(entry.Key.AsString()); + mStream.Write(b.Length); + mStream.Write(b); + } + catch (Exception exp) + { + SprotoUtil.DumpObject(obj); + SprotoUtil.DumpObject(entry.Key); + UnityEngine.Debug.LogError(exp); + } + } + else if (entry.Key.IsInt ()) { + mStream.Write ((int)4); + mStream.Write (entry.Key.AsInt ()); + } + else if (entry.Key.IsLong ()) { + mStream.Write ((int)8); + mStream.Write (entry.Key.AsLong ()); + } + else if (entry.Key.IsBoolean ()) { + // boolean should not be here + return false; + } + else { + int obj_begin = mStream.Position; + int obj_size = 0; + mStream.Write (obj_size); + + if (EncodeInternal (entry.Value, entry.Key, mStream) == false) + return false; + + int obj_end = mStream.Position; + obj_size = (int)(obj_end - obj_begin - 4); + mStream.Position = obj_begin; + mStream.Write (obj_size); + mStream.Position = obj_end; + } + } + } + + int end = mStream.Position; + mStream.Position = begin; + mStream.Write (fn); + mStream.Position = end; + + return true; + } + + public SpObject Decode (string proto, SpStream stream) { + return Decode (mTypeManager.GetType (proto), stream); + } + + public SpObject Decode (SpType type, SpStream stream) { + if (type == null || stream == null) + return null; + + //mStream = stream; + return DecodeInternal (type, stream); + } + + private SpObject DecodeInternal (SpType type, SpStream mStream) { + if (mStream == null || type == null) + return null; + + // buildin type decoding should not be here + if (mTypeManager.IsBuildinType (type)) + return null; + + SpObject obj = null; + + if (type.Fields != null && type.Fields.Length > 0) + { + var typefilenames = type.FiledsNames; + if (typefilenames != null && typefilenames.Length > 0) + obj = SpObject.CreateWithKeys(typefilenames); + else + obj = new SpObject(); + } + else + obj = new SpObject(); + + List tags = new List (); + int current_tag = 0; + + short fn = mStream.ReadInt16 (); + for (short i = 0; i < fn; i++) { + int value = (int)mStream.ReadUInt16 (); + + if (value == 0) { + tags.Add (current_tag); + current_tag++; + } + else { + if (value % 2 == 0) { + SpField f = type.GetFieldByTag (current_tag); + if (f != null){ + value = value / 2 - 1; + if (f.Type == mTypeManager.Integer) + { + obj.Insert(f.Name, value); + } + else if (f.Type == mTypeManager.Boolean) + { + obj.Insert(f.Name, (value == 0 ? false : true)); + } + else + { + return null; + } + } + current_tag++; + } + else { + current_tag += (value + 1) / 2; + } + } + } + + foreach (int tag in tags) { + SpField f = type.GetFieldByTag (tag); + if (f == null) { + int size = mStream.ReadInt32(); + mStream.ReadBytes(size); + }else if (f.IsArray) { + int size = mStream.ReadInt32 (); + + if (f.Type == mTypeManager.Integer) { + byte n = mStream.ReadByte (); + int count = (size - 1) / n; + SpObject arr = SpObject.CreateArrayWithCount(count); + for (int i = 0; i < count; i++) { + switch (n) { + case 4: + arr.Append (mStream.ReadInt32 ()); + break; + case 8: + arr.Append (mStream.ReadInt64 ()); + break; + default: + return null; + } + } + obj.Insert (f.Name, arr); + } + else if (f.Type == mTypeManager.Boolean) { + SpObject arr = new SpObject (); + for (int i = 0; i < size; i++) { + arr.Append (mStream.ReadBoolean ()); + } + obj.Insert (f.Name, arr); + } + else if (f.Type == mTypeManager.String) { + SpObject arr = new SpObject (); + while (size > 0) { + int str_len = mStream.ReadInt32 (); + size -= 4; + arr.Append (Encoding.UTF8.GetString (mStream.ReadBytes (str_len), 0, str_len)); + size -= str_len; + } + obj.Insert (f.Name, arr); + } + else if (f.Type == mTypeManager.Bytes) + { + SpObject arr = new SpObject(); + while (size > 0) + { + int str_len = mStream.ReadInt32(); + size -= 4; + arr.Append(mStream.ReadBytes(str_len)); + size -= str_len; + } + obj.Insert(f.Name, arr); + } + else if (f.Type == null) { + // unknown type + mStream.ReadBytes (size); + } + else { + SpObject arr = new SpObject (); + while (size > 0) { + int obj_len = mStream.ReadInt32 (); + size -= 4; + arr.Append (DecodeInternal (f.Type, mStream)); + size -= obj_len; + } + obj.Insert (f.Name, arr); + } + } + else { + int size = mStream.ReadInt32 (); + + if (f.Type == mTypeManager.Integer) { + switch (size) { + case 4: + obj.Insert (f.Name, mStream.ReadInt32 ()); + break; + case 8: + obj.Insert (f.Name, mStream.ReadInt64 ()); + break; + default: + return null; + } + } + else if (f.Type == mTypeManager.Boolean) { + // boolean should not be here + return null; + } + else if (f.Type == mTypeManager.String) { + obj.Insert (f.Name, Encoding.UTF8.GetString (mStream.ReadBytes (size), 0, size)); + } + else if (f.Type == mTypeManager.Bytes) { + obj.Insert(f.Name, mStream.ReadBytes(size)); + } + else if (f.Type == null) { + // unknown type + mStream.ReadBytes (size); + } + else { + obj.Insert (f.Name, DecodeInternal (f.Type, mStream)); + } + } + } + + if (obj.IsTable()) + { + var dict = obj.Value as SpDict; + + if (dict != null) + { + bool hasData = false; + var values = dict.Values; + if (values != null) + { + for (int i = 0; i < values.Length; i++) + { + if (values[i] != null) + { + hasData = true; + break; + } + } + } + if (!hasData) + return new SpObject(); + } + } + + return obj; + } + + private bool IsTypeMatch (SpField f, SpObject o) { + if (f == null || f.Type == null || o == null) + return false; + + if (f.IsArray) { + if (o.IsArray ()) + return true; + } + else if (f.Type == mTypeManager.String) { + if (o.IsString ()||o.IsBytes ()) + return true; + } + else if (f.Type == mTypeManager.Boolean) { + if (o.IsBoolean ()) + return true; + } + else if (f.Type == mTypeManager.Integer) { + if (o.IsInt () || o.IsLong ()) + return true; + } + else if (f.Type == mTypeManager.Bytes){ + if (o.IsBytes()) + return true; + } + else { + if (o.IsTable ()) + return true; + } + + return false; + } +} diff --git a/Assets/LuaFramework/Scripts/Framework/Core/Message.cs.meta b/Assets/Scripts/Framework/sproto/src/SpCodec.cs.meta similarity index 78% rename from Assets/LuaFramework/Scripts/Framework/Core/Message.cs.meta rename to Assets/Scripts/Framework/sproto/src/SpCodec.cs.meta index 269714e..8e8b950 100644 --- a/Assets/LuaFramework/Scripts/Framework/Core/Message.cs.meta +++ b/Assets/Scripts/Framework/sproto/src/SpCodec.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7c43b926e665fea43b8b5f49e21fecb8 +guid: 26d4cc38a1c76bb4a8db470df54df72c MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/Scripts/Framework/sproto/src/SpDict.cs b/Assets/Scripts/Framework/sproto/src/SpDict.cs new file mode 100644 index 0000000..f50bf89 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpDict.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +public class SpDict +{ + protected string[] keys; + protected SpObject[] values; + public string[] Keys { get { return keys; } } + public SpObject[] Values { get { return values; } } + + public SpDict(string[] keys) + { + this.keys = keys; + this.values = new SpObject[keys.Length]; + } + + public SpObject this[string key] + { + get + { + int idx = IndexOf(key); + if (idx >= 0 && idx < values.Length) + return values[idx]; + return null; + } + set + { + int idx = IndexOf(key); + if (idx >= 0 && idx < values.Length) + values[idx] = value; + } + } + + public void Add(string key, SpObject value) + { + int idx = IndexOf(key); + if (idx >= 0 && idx < values.Length) + values[idx] = value; + } + public bool ContainsKey(string key) + { + int idx = IndexOf(key); + return idx >= 0; + } + + public bool Remove(string key) + { + int idx = IndexOf(key); + if (idx >= 0 && idx < values.Length) + values[idx] = null; + return idx >= 0; + } + + public bool TryGetValue(string key, out SpObject value) + { + int idx = IndexOf(key); + if (idx < 0) + { + value = null; + return false; + } + value = values[idx]; + return true; + } + + protected int IndexOf(string key) + { + for (int i = 0; i < keys.Length; i++) + { + if (keys[i] == key) + return i; + } + return -1; + } + + class SpDictEnumerator:IEnumerator + { + int i = 0; + SpDict dict; + public SpDictEnumerator(SpDict dict) + { + this.dict = dict; + i = 0; + } + public object Current { get { return dict.values[i]; } } + public bool MoveNext() + { + i++; + return (i < dict.keys.Length); + } + public void Reset() + { + i = 0; + } + } + + public IEnumerator GetEnumerator() + { + return new SpDictEnumerator(this); + } +} + diff --git a/Assets/LuaFramework/Scripts/Controller/Command/SocketCommand.cs.meta b/Assets/Scripts/Framework/sproto/src/SpDict.cs.meta similarity index 78% rename from Assets/LuaFramework/Scripts/Controller/Command/SocketCommand.cs.meta rename to Assets/Scripts/Framework/sproto/src/SpDict.cs.meta index f544f8d..dcbcab0 100644 --- a/Assets/LuaFramework/Scripts/Controller/Command/SocketCommand.cs.meta +++ b/Assets/Scripts/Framework/sproto/src/SpDict.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2384cc1ec84c1674793c84b948d36fe8 +guid: 3c451d06d7de65b4abe886e403459121 MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/Scripts/Framework/sproto/src/SpField.cs b/Assets/Scripts/Framework/sproto/src/SpField.cs new file mode 100644 index 0000000..353138a --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpField.cs @@ -0,0 +1,34 @@ +using System.Collections; +using System; + +[Serializable] +public class SpField { + public string Name; + [NonSerialized] + public SpType Type; + public string TypeName; + public int Tag; + public bool IsArray; + + //private SpTypeManager mTypeManager; + + public SpField (string name, short tag, string type, bool array) { + Name = name; + Tag = tag; + TypeName = type; + IsArray = array; + + //mTypeManager = m; + } + + public bool CheckAndUpdate(SpTypeManager typeManager) + { + if (Type != null) + return true; + + // use GetTypeNoCheck instead of GetType, to prevent infinit GetType call + // when a type reference itself like : foobar { a 0 : foobar } + Type = typeManager.GetTypeNoCheck(TypeName); + return (Type != null); + } +} diff --git a/Assets/LuaFramework/Scripts/Framework/Core/View.cs.meta b/Assets/Scripts/Framework/sproto/src/SpField.cs.meta similarity index 78% rename from Assets/LuaFramework/Scripts/Framework/Core/View.cs.meta rename to Assets/Scripts/Framework/sproto/src/SpField.cs.meta index 4428aff..44f213f 100644 --- a/Assets/LuaFramework/Scripts/Framework/Core/View.cs.meta +++ b/Assets/Scripts/Framework/sproto/src/SpField.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 65cb27367c0951e4abc2cbfe1a5a6e08 +guid: 06375b3cd2ba57942b071dd14342ce6f MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/Scripts/Framework/sproto/src/SpObject.cs b/Assets/Scripts/Framework/sproto/src/SpObject.cs new file mode 100644 index 0000000..0fc94c9 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpObject.cs @@ -0,0 +1,443 @@ +using System.Collections.Generic; +using System; +using UnityEngine; + +public class SpObject +{ + + public enum ArgType + { + Table, + Array, + Boolean, + String, + Int, + Long, + Bytes, + Null, + } + + private object mValue; + private ArgType mType; + + public static SpObject CreateWithKeys(string[] keys) + { + var obj = new SpObject(); + obj.mType = ArgType.Table; + obj.mValue = new SpDict(keys); + return obj; + } + public static SpObject CreateArrayWithCount(int count) + { + var obj = new SpObject(); + obj.mType = ArgType.Array; + obj.mValue = new List(count); + return obj; + } + + public SpObject() + { + mValue = null; + mType = ArgType.Null; + } + + public SpObject(object arg) + { + mValue = arg; + mType = ArgType.Null; + + if (mValue != null) + { + Type t = mValue.GetType(); + if (t == typeof(long)) + { + mType = ArgType.Long; + } + else if (t == typeof(int)) + { + mType = ArgType.Int; + } + else if (t == typeof(string)) + { + mType = ArgType.String; + } + else if (t == typeof(bool)) + { + mType = ArgType.Boolean; + } + else if (t == typeof(byte[])) + { + mType = ArgType.Bytes; + } + } + } + + public SpObject(ArgType type, params object[] args) + { + mType = ArgType.Null; + + switch (type) + { + case ArgType.Array: + foreach (object arg in args) + { + Append(arg); + } + break; + case ArgType.Table: + for (int i = 0; i < args.Length; i += 2) + { + Insert((string)args[i], args[i + 1]); + } + break; + } + } + + public bool IsTable() + { + return (mType == ArgType.Table); + } + + public Dictionary AsTable() + { + return mValue as Dictionary; + } + public SpDict AsSpDict() + { + return mValue as SpDict; + } + + public void Insert(string key, SpObject obj) + { + if (IsTable() == false) + { + mType = ArgType.Table; + mValue = new Dictionary(); + } + var d = AsSpDict(); + if (d != null) + { + d[key] = obj; + return; + } + AsTable()[key] = obj; + } + + public void Insert(string key, object value) + { + if (value.GetType() == typeof(SpObject)) + Insert(key, (SpObject)value); + else + Insert(key, new SpObject(value)); + } + + public bool IsArray() + { + return (mType == ArgType.Array); + } + + public List AsArray() + { + return mValue as List; + } + + public void Append(SpObject obj) + { + if (IsArray() == false) + { + mType = ArgType.Array; + mValue = new List(); + } + AsArray().Add(obj); + } + + public void Append(object value) + { + if (value.GetType() == typeof(SpObject)) + Append((SpObject)value); + else + Append(new SpObject(value)); + } + + public bool IsLong() + { + return (mType == ArgType.Long); + } + + public long AsLong() + { + if (IsLong()) + return (long)mValue; + return Convert.ToInt64(mValue); + } + + public bool IsInt() + { + return (mType == ArgType.Int); + } + + public int AsInt() + { + if (mType == ArgType.Int) + { + return Convert.ToInt32(mValue); + } + else + { + GameLogger.LogError("SpObject AsInt is Error"); + return 0; + } + //return (int)mValue; + } + + public bool IsBoolean() + { + return (mType == ArgType.Boolean); + } + + public bool AsBoolean() + { + if (mType == ArgType.Boolean) + { + return Convert.ToBoolean(mValue); + } + else + { + GameLogger.LogError("SpObject AsBoolean is Error"); + return false; + } + + //return (bool)mValue; + } + + public bool IsString() + { + return (mType == ArgType.String); + } + + public string AsString() + { + return mValue as string; + } + + public bool IsBytes() + { + return (mType == ArgType.Bytes); + } + + public byte[] AsBytes() + { + return mValue as byte[]; + } + + public object Value + { + get { return mValue; } + //set { mValue = value; } + } + + public void SetValue(object v) + { + mValue = v; + } + + public SpObject this[string key] + { + get + { + if (IsTable() == false) + return null; + var d = AsSpDict(); + if (d != null) + return d[key]; + Dictionary t = AsTable(); + if (t.ContainsKey(key) == false) + return null; + return t[key]; + } + set + { + if (IsTable() == false) + return; + var d = AsSpDict(); + if (d != null) + { + d[key] = value; + return; + } + Dictionary t = AsTable(); + t[key] = value; + } + } + + public SpObject this[int index] + { + get + { + if (IsArray() == false) + return null; + + if (index < 0) + return null; + + List a = AsArray(); + if (a.Count <= index) + return null; + return a[index]; + } + set + { + if (IsArray() == false) + return; + + if (index < 0) + return; + + List a = AsArray(); + if (a.Count <= index) + return; + a[index] = value; + } + } + + public SpObject DeepClone() + { + SpObject spObj = new SpObject(); + if (mValue == null) + return spObj; + + Type t = mValue.GetType(); + if (t == typeof(string)) + { + string sValue = (string)mValue; + string dValue = (sValue == null) ? null : (string)sValue.Clone(); + spObj.SetValue(dValue); + spObj.mType = ArgType.String; + } + else if (t == typeof(byte[])) + { + Byte[] sValue = this.AsBytes(); + Byte[] dValue = null; + if (sValue != null && sValue.Length > 0) + { + dValue = new byte[sValue.Length]; + for (int i = 0; i < sValue.Length; ++i) + dValue[i] = sValue[i]; + } + spObj.SetValue(dValue); + spObj.mType = ArgType.Bytes; + } + else if (t == typeof(List)) + { + List dValues = new List(); + List sValues = this.AsArray(); + foreach (SpObject sp in sValues) + { + if (sp != null) + dValues.Add(sp.DeepClone()); + else + dValues.Add(null); + } + spObj.SetValue(dValues); + spObj.mType = ArgType.Array; + } + else if (t == typeof(Dictionary)) + { + Dictionary dValues = new Dictionary(); + Dictionary sValues = this.AsTable(); + foreach (KeyValuePair p in sValues) + { + if (p.Value != null) + dValues.Add(p.Key, p.Value.DeepClone()); + else + dValues.Add(p.Key, null); + } + spObj.SetValue(dValues); + spObj.mType = ArgType.Table; + } + else if (t == typeof(SpDict)) + { + SpDict sValues = this.AsSpDict(); + SpDict dValues = new SpDict(sValues.Keys); + + for (int i = 0; i < sValues.Keys.Length; ++i) + { + dValues.Keys[i] = sValues.Keys[i]; + dValues.Values[i] = sValues.Values[i] == null ? null : sValues.Values[i].DeepClone(); + } + spObj.SetValue(dValues); + spObj.mType = ArgType.Table; + } + else if (t == typeof(int)) + { + spObj.mType = ArgType.Int; + spObj.SetValue(mValue); + } + else if (t == typeof(bool)) + { + spObj.mType = ArgType.Boolean; + spObj.SetValue(mValue); + } + else if (t == typeof(long)) + { + spObj.mType = ArgType.Long; + spObj.SetValue(mValue); + } + + return spObj; + } + + #region 解析安全接口 + + public static string AsString(SpObject spObj, string key, string defaultValue = "", bool logNull = false) + { + if (null != spObj[key]) return spObj[key].AsString(); + else + { + if (logNull) GameLogger.LogError("SpObject AsString Error, key: " + key); + return defaultValue; + } + } + + public static int AsInt(SpObject spObj, string key, int defaultValue = 0, bool logNull = false) + { + if (null != spObj[key]) return spObj[key].AsInt(); + else + { + if (logNull) GameLogger.LogError("SpObject AsInt Error, key: " + key); + return defaultValue; + } + } + + public static bool AsBoolean(SpObject spObj, string key, bool defaultValue = false, bool logNull = false) + { + if (null != spObj[key]) return spObj[key].AsBoolean(); + else + { + if (logNull) GameLogger.LogError("SpObject AsBoolean Error, key: " + key); + return defaultValue; + } + } + + public static long AsLong(SpObject spObj, string key, long defaultValue = 0, bool logNull = false) + { + if (null != spObj[key]) return spObj[key].AsLong(); + else + { + if (logNull) GameLogger.LogError("SpObject AsBoolean Error, key: " + key); + return defaultValue; + } + } + + public static List AsArray(SpObject spObj, string key, bool logNull = false) + { + if (null != spObj[key]) return spObj[key].AsArray(); + else + { + if (logNull) GameLogger.LogError("SpObject AsBoolean Error, key: " + key); + return new List(); + } + } + #endregion 解析安全接口 + +} diff --git a/Assets/LuaFramework/Scripts/Framework/Core/Manager.cs.meta b/Assets/Scripts/Framework/sproto/src/SpObject.cs.meta similarity index 78% rename from Assets/LuaFramework/Scripts/Framework/Core/Manager.cs.meta rename to Assets/Scripts/Framework/sproto/src/SpObject.cs.meta index 15b023d..327867f 100644 --- a/Assets/LuaFramework/Scripts/Framework/Core/Manager.cs.meta +++ b/Assets/Scripts/Framework/sproto/src/SpObject.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7c71b17dd8e0c314fb7b2465e5717b5e +guid: 93aca402cc8e66a4b8650a31e6fe1686 MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/Scripts/Framework/sproto/src/SpPacker.cs b/Assets/Scripts/Framework/sproto/src/SpPacker.cs new file mode 100644 index 0000000..5c4c719 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpPacker.cs @@ -0,0 +1,183 @@ +using System.Collections; +using System.IO; +using System; + +public class SpPacker { + private static int PackSeg (byte[] src, int src_offset, SpStream output, int n) { + byte header = 0; + int notzero = 0; + + int dest_begin = output.Position; + output.Write((byte)0); + + for (int i = 0; i < 8; i++) { + if (src[src_offset + i] != 0) { + notzero++; + header |= (byte)(1 << i); + + output.Write (src[src_offset + i]); + } + } + + if ((notzero == 7 || notzero == 6) && n > 0) + notzero = 8; + + if (notzero == 8) { + if (n > 0) + return 8; + else + return 10; + } + + int dest_end = output.Position; + output.Position = dest_begin; + output.Write (header); + output.Position = dest_end; + + return notzero + 1; + } + + public static void WriteFF (byte[] src, int src_offset, SpStream output, int n) { + output.Write ((byte)0xff); + output.Write ((byte)(n - 1)); + output.Write (src, src_offset, n * 8); + } + + public static SpStream Pack (SpStream input) { + SpStream stream = new SpStream (); + + int pos = input.Position; + if (Pack (input, stream) == false) { + int size = stream.Position; + size = ((size + 7) / 8) * 8; + stream = new SpStream (size); + + input.Position = pos; + // do we need this check? it's not possible it will return false this time + if (Pack (input, stream) == false) + return null; + } + + return stream; + } + + public static bool Pack (SpStream input, SpStream output) { + int src_size = input.Length; + if (src_size % 8 != 0) { + int new_size = ((src_size + 7) / 8) * 8; + if (input.Capacity < new_size) { + SpStream new_input = new SpStream (new_size); + Array.Copy (input.Buffer, input.Offset, new_input.Buffer, new_input.Offset, input.Length); + new_input.Position = new_input.Offset; + input = new_input; + } + else { + int pos = input.Position; + input.Position = input.Tail; + for (int i = src_size; i < new_size; i++) { + input.Write ((byte)0); + } + input.Position = pos; + } + } + + int src_offset = input.Offset; + byte[] src = input.Buffer; + + int ff_n = 0; + int ff_src_start = 0; + int ff_dest_start = 0; + + for (; src_offset < src_size; src_offset += 8) { + int pos = output.Position; + int n = PackSeg (src, src_offset, output, ff_n); + + if (n == 10) { + ff_src_start = src_offset; + ff_dest_start = pos; + ff_n = 1; + } + else if (n == 8 && ff_n > 0) { + ff_n++; + if (ff_n == 256) { + output.Position = ff_dest_start; + WriteFF (src, ff_src_start, output, 256); + ff_n = 0; + } + } + else { + if (ff_n > 0) { + output.Position = ff_dest_start; + WriteFF (src, ff_src_start, output, ff_n); + ff_n = 0; + } + } + + output.Position = pos + n; + } + + if (ff_n > 0) { + output.Position = ff_dest_start; + WriteFF (src, ff_src_start, output, ff_n); + output.CutTailToPosition(); + } + + return (output.IsOverflow () == false); + } + + public static SpStream Unpack (SpStream input) { + SpStream stream = SpStreamCache.Get(); // new SpStream (); + + int pos = input.Position; + if (Unpack (input, stream) == false) { + stream = new SpStream (stream.Position); + + input.Position = pos; + if (Unpack (input, stream) == false) + return null; + } + + return stream; + } + + public static bool Unpack (SpStream input, SpStream output) { + int src_size = input.Tail; + int src_offset = input.Offset; + byte[] src = input.Buffer; + + while (src_offset < src_size) { + byte header = src[src_offset]; + src_offset++; + + if (header == 0xff) { + if (src_offset >= src_size) + return false; + + int n = (src[src_offset] + 1) * 8; + if (src_size - src_offset < n + 1) + return false; + + src_offset++; + output.Write (src, src_offset, n); + src_offset += n; + } + else { + for (int i = 0; i < 8; i++) { + int nz = (header >> i) & 1; + if (nz != 0) { + if (src_offset >= src_size) + return false; + + output.Write (src[src_offset]); + src_offset++; + } + else { + output.Write ((byte)0); + } + } + } + } + + return (output.IsOverflow () == false); + } +} diff --git a/Assets/Scripts/Framework/sproto/src/SpPacker.cs.meta b/Assets/Scripts/Framework/sproto/src/SpPacker.cs.meta new file mode 100644 index 0000000..c5b5ad3 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpPacker.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6b3846325f009bd488e585d86c0927a4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Scripts/Framework/sproto/src/SpProtoParser.cs b/Assets/Scripts/Framework/sproto/src/SpProtoParser.cs new file mode 100644 index 0000000..f181c68 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpProtoParser.cs @@ -0,0 +1,185 @@ +using System.Collections; +using System; +using UnityEngine; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +public interface SpProtoParserListener { + void OnNewType(SpType type); + void OnNewProtocol (SpProtocol protocol); +} + +public class SpProtoParser { + private SpProtoParserListener mListener; + private static char[] sDelimiters = new char[] {'{', '}', '\n'}; + private static char[] sSpace = new char[] {' ', '\t', '\n'}; + + private SpProtocol mCurrentProtocol; + private SpType mCurrentType; + private SpType mLastType; + + public SpProtoParser (SpProtoParserListener linstener) { + mListener = linstener; + } + + public void Parse (Stream stream) { + Parse (ReadAll (stream)); + } + + public void Parse (string str) { + mCurrentProtocol = null; + mCurrentType = null; + mLastType = null; + + str = PreProcess (str); + Scan (str, 0); + } + + private string ReadAll (Stream stream) { + string str = ""; + + byte[] buf = new byte[1024]; + int len = stream.Read (buf, 0, buf.Length); + while (len > 0) { + str += Encoding.UTF8.GetString (buf, 0, len); + len = stream.Read (buf, 0, buf.Length); + } + + return str; + } + + private string PreProcess (string str) { + // TODO : trim comment + return str.Replace ("\r", string.Empty).Trim (); + } + + private void Scan (string str, int start) { + System.Collections.Generic.List mCurSpFieldList = new System.Collections.Generic.List(); + while (start < str.Length) + { + + int pos = str.IndexOfAny(sDelimiters, start); + if (pos < 0) + return; + + switch (str[pos]) + { + case '{': + string title = str.Substring(start, pos - start).Trim(); + if (IsProtocol(title)) + { + mCurrentProtocol = NewProtocol(title); + } + else + { + mLastType = mCurrentType; + mCurrentType = NewType(title); + } + break; + case '}': + if (mCurrentType != null) + { + if (mCurSpFieldList.Count > 0) + { + mCurrentType.Fields = mCurSpFieldList.ToArray(); + mCurSpFieldList.Clear(); + } + mListener.OnNewType(mCurrentType); + if (mCurrentProtocol != null) + mCurrentProtocol.AddType(mCurrentType); + mCurrentType = mLastType; + mLastType = null; + } + else if (mCurrentProtocol != null) + { + mListener.OnNewProtocol(mCurrentProtocol); + mCurrentProtocol = null; + } + break; + case '\n': + SpField f = NewField(str, start, pos); + if (f!=null) + { + int curCount = mCurSpFieldList.Count; + if (f.Tag == curCount){ + mCurSpFieldList.Add(f); + }else if (f.Tag < curCount){ + mCurSpFieldList[f.Tag] = f; + }else if (f.Tag > curCount){ + for (int i = curCount; i < f.Tag; i++) + mCurSpFieldList.Add(null); + mCurSpFieldList.Add(f); + } + } + + //if (f != null && mCurrentType != null) + //{ + // mCurrentType.AddField(f); + //} + break; + } + + start = pos + 1; + } + //Scan (str, start); + } + + private bool IsProtocol (string str) { + return (str.IndexOfAny (sSpace) >= 0); + } + + private SpProtocol NewProtocol (string str) { + string[] words = str.Split (sSpace); + if (words.Length != 2) + return null; + + SpProtocol protocol = new SpProtocol (words[0], int.Parse (words[1])); + return protocol; + } + + private SpType NewType (string str) { + if (str[0] == '.') { + str = str.Substring (1); + } + else { + if (mLastType != null) + str = mLastType.Name + "." + str; + + if (mCurrentProtocol != null) + str = mCurrentProtocol.Name + "." + str; + } + + SpType t = new SpType (str); + return t; + } + + + private static char[] sFieldSpace = new char[] { ' ', '\t', '\n', ':' }; + private static string[] SplitSpace(string str) + { + return str.Split(sFieldSpace, StringSplitOptions.RemoveEmptyEntries); + } + + private SpField NewField(string str, int startPos, int endPos) + { + str = str.Substring(startPos, endPos - startPos); + string[] words = null; + words = SplitSpace(str); + if (words == null) + return null; + if (words.Length != 3) + return null; + + string name = words[0]; + short tag = short.Parse (words[1]); + string type = words[2]; + bool array = false; + if (type[0] == '*') { + array = true; + type = type.Substring (1); + } + SpField f = new SpField (name, tag, type, array); + return f; + } +} diff --git a/Assets/Scripts/Framework/sproto/src/SpProtoParser.cs.meta b/Assets/Scripts/Framework/sproto/src/SpProtoParser.cs.meta new file mode 100644 index 0000000..c893a04 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpProtoParser.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0e5976b953048c74bb16c57c1b947b4d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Scripts/Framework/sproto/src/SpProtocol.cs b/Assets/Scripts/Framework/sproto/src/SpProtocol.cs new file mode 100644 index 0000000..09a711b --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpProtocol.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System; + +[Serializable] +public class SpProtocol { + public string Name; + public int Tag; + + [NonSerialized] + public SpType Request; + [NonSerialized] + public SpType Response; + + public SpProtocol (string name, int tag) { + Name = name; + Tag = tag; + } + + public void AddType (SpType type) { + if (type.Name.Equals (Name + ".request")) + Request = type; + else if (type.Name.Equals (Name + ".response")) + Response = type; + } +} diff --git a/Assets/Scripts/Framework/sproto/src/SpProtocol.cs.meta b/Assets/Scripts/Framework/sproto/src/SpProtocol.cs.meta new file mode 100644 index 0000000..0f9dd9b --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpProtocol.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 64b1c85858507764faf99d60e9920fd8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Scripts/Framework/sproto/src/SpRpc.cs b/Assets/Scripts/Framework/sproto/src/SpRpc.cs new file mode 100644 index 0000000..bb8a200 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpRpc.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +public enum SpRpcOp +{ + Request, + Response, + Unknown, +} + +public class SpRpcResult +{ + public int Session; + public SpProtocol Protocol; + public SpRpcOp Op; + public SpObject Arg; + + // 是否已经处理了 + public bool bProcess = false; + + public SpRpcResult() + { + Session = 0; + Protocol = null; + Op = SpRpcOp.Unknown; + Arg = null; + } + + public SpRpcResult(int s, SpProtocol p, SpRpcOp o, SpObject a) + { + Session = s; + Protocol = p; + Op = o; + Arg = a; + } +} + +public class SpRpc +{ + private SpTypeManager mHostTypeManager; + private SpTypeManager mAttachTypeManager; + + private SpType mHeaderType; + private Dictionary mSessions = new Dictionary(); + + public SpTypeManager hostTypeManager { get { return mHostTypeManager; } } + public SpTypeManager attachTypeManager { get { return mAttachTypeManager; } } + + public SpRpc(SpTypeManager tm, SpType t) + { + mHostTypeManager = tm; + mHeaderType = t; + } + + public void Attach(string proto) + { + Attach(SpTypeManager.Import(proto)); + } + + public void Attach(SpTypeManager tm) + { + mAttachTypeManager = tm; + } + + public SpStream Request(string proto) + { + return Request(proto, null); + } + + public SpStream Request(string proto, SpObject args) + { + return Request(proto, args, 0); + } + + public SpStream Request(string proto, SpObject args, int session) + { + SpStream encode_stream = EncodeRequest(proto, args, session); + encode_stream.Position = 0; + return SpPacker.Pack(encode_stream); + } + + public bool Request(string proto, SpObject args, int session, SpStream stream) + { + SpStream encode_stream = EncodeRequest(proto, args, session); + encode_stream.Position = 0; + return SpPacker.Pack(encode_stream, stream); + } + + private SpStream EncodeRequest(string proto, SpObject args, int session) + { + if (mAttachTypeManager == null || mHostTypeManager == null || mHeaderType == null) + return null; + + SpProtocol protocol = mAttachTypeManager.GetProtocolByName(proto); + if (protocol == null) + return null; + + SpObject header = new SpObject(); + header.Insert("type", protocol.Tag); + if (session != 0) + header.Insert("session", session); + + SpStream stream = mHostTypeManager.Codec.Encode(mHeaderType, header); + if (stream == null) + return null; + + if (args != null) + { + if (mAttachTypeManager.Codec.Encode(protocol.Request, args, stream) == false) + { + if (stream.IsOverflow()) + { + if (stream.Position > SpCodec.MAX_SIZE) + return null; + + int size = stream.Position; + size = ((size + 7) / 8) * 8; + stream = new SpStream(size); + if (mAttachTypeManager.Codec.Encode(protocol.Request, args, stream) == false) + return null; + } + else + { + return null; + } + } + } + + if (session != 0) + { + mSessions[session] = protocol; + } + + return stream; + } + + public SpStream Response(int session, SpObject args) + { + SpObject header = new SpObject(); + header.Insert("session", session); + + SpStream encode_stream = new SpStream(); + mHostTypeManager.Codec.Encode(mHeaderType, header, encode_stream); + + if (session != 0 && mSessions.ContainsKey(session)) + { + mHostTypeManager.Codec.Encode(mSessions[session].Response, args, encode_stream); + } + + SpStream pack_stream = new SpStream(); + encode_stream.Position = 0; + SpPacker.Pack(encode_stream, pack_stream); + + pack_stream.Position = 0; + return pack_stream; + } + + public SpRpcResult Dispatch(SpStream stream) + { + SpStream unpack_stream = SpPacker.Unpack(stream); + + unpack_stream.Position = 0; + SpObject header = mHostTypeManager.Codec.Decode(mHeaderType, unpack_stream); + + int session = 0; + if (header["session"] != null) + { + session = header["session"].AsInt(); + } + + if (header["type"] != null) + { + int type = header["type"].AsInt(); + + bool bProcess = LuaFramework.NetworkManager.OnRequestData(unpack_stream, type); + if (!bProcess) + { + //lua单独处理 + return null; + } + // handle request + SpProtocol protocol = mHostTypeManager.GetProtocolByTag(type); + if (protocol == null) + { + // 找不到服务器推送的消息协议,返回 + GameLogger.LogError("not find sproto message id, " + type); + SpStreamCache.Collect(unpack_stream); + return null; + } + + SpObject obj = mHostTypeManager.Codec.Decode(protocol.Request, unpack_stream); + if (session != 0) + mSessions[session] = protocol; + SpStreamCache.Collect(unpack_stream); + return new SpRpcResult(session, protocol, SpRpcOp.Request, obj); + } + else + { + bool bProcess = true; + SpProtocol protocol = null; + if (mSessions.TryGetValue(session, out protocol)) + { + bProcess = LuaFramework.NetworkManager.OnResponseData(unpack_stream, protocol, session); + } + else + { + bProcess = LuaFramework.NetworkManager.OnResponseData(unpack_stream, protocol, session); + } + + mSessions.Remove(session); + + if (!bProcess) + { + //lua单独处理 + //return null; + SpRpcResult result = new SpRpcResult(session, protocol, SpRpcOp.Response, null); + result.bProcess = true; + return result; + } + // handle response + if (protocol == null) + { + GameLogger.LogError("not contain session: " + session); + //return new SpRpcResult(); + return null; + } + + //SpProtocol protocol = mSessions[session]; + + + if (protocol == null) + return new SpRpcResult(); + + if (protocol.Response == null) + return new SpRpcResult(session, protocol, SpRpcOp.Response, null); + + SpObject obj = mAttachTypeManager.Codec.Decode(protocol.Response, unpack_stream); + SpStreamCache.Collect(unpack_stream); + return new SpRpcResult(session, protocol, SpRpcOp.Response, obj); + } + + } + + //处理一些lua中发送的协议 + public void AddSession(int session, SpProtocol protocol, int tag) + { + if (session != 0) + { + if (protocol == null) + { + //mAttachTypeManager (c2s) + protocol = mAttachTypeManager.GetProtocolByTag(tag); + //s2c + //protocol = mHostTypeManager.GetProtocolByTag(tag); + } + mSessions[session] = protocol; + } + } + + + public static SpRpc Create(Stream proto, string package) + { + return Create(SpTypeManager.Import(proto), package); + } + + public static SpRpc Create(string proto, string package) + { + return Create(SpTypeManager.Import(proto), package); + } + + public static SpRpc Create(SpTypeManager tm, string package) + { + if (tm == null) + return null; + + SpType t = tm.GetType(package); + if (t == null) + return null; + + SpRpc rpc = new SpRpc(tm, t); + return rpc; + } +} diff --git a/Assets/Scripts/Framework/sproto/src/SpRpc.cs.meta b/Assets/Scripts/Framework/sproto/src/SpRpc.cs.meta new file mode 100644 index 0000000..da7953c --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpRpc.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fb20e6efbe56da64aaf2bb9e28a95098 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Scripts/Framework/sproto/src/SpStream.cs b/Assets/Scripts/Framework/sproto/src/SpStream.cs new file mode 100644 index 0000000..0bc06f4 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpStream.cs @@ -0,0 +1,210 @@ +using System.Collections.Generic; +using System; + +public class SpStream { + const int DEFAULT_SIZE = 2050; + + private byte[] mBuffer; + private int mOffset; + private int mLength; + private int mPosition; + private int mTail; + + public SpStream () + : this (DEFAULT_SIZE) { + } + + public SpStream (int len) + : this (new byte[len]) { + } + + public SpStream (byte[] b) + : this (b, 0, b.Length) { + } + + public SpStream (byte[] b, int o, int c) + : this (b, 0, b.Length, -1) { + } + + public SpStream (byte[] b, int o, int c, int t) { + mBuffer = b; + mLength = o + c; + mOffset = o; + mPosition = mOffset; + + if (t >= 0) + mTail = o + t; + else + mTail = mPosition; + } + + public void Reset () { + mPosition = mOffset; + mTail = mPosition; + } + + public bool IsOverflow () { + return (mPosition > mLength); + } + + public byte ReadByte () { + int pos = mPosition; + mPosition += 1; + return mBuffer[pos]; + } + + public bool ReadBoolean () { + return (ReadByte () != 0); + } + + public short ReadInt16 () { + int pos = mPosition; + mPosition += 2; + return BitConverter.ToInt16 (mBuffer, pos); + } + + public ushort ReadUInt16 () { + int pos = mPosition; + mPosition += 2; + return BitConverter.ToUInt16 (mBuffer, pos); + } + + public int ReadInt32 () { + int pos = mPosition; + mPosition += 4; + return BitConverter.ToInt32 (mBuffer, pos); + } + + public long ReadInt64 () { + int pos = mPosition; + mPosition += 8; + return BitConverter.ToInt64 (mBuffer, pos); + } + + public byte[] ReadBytes (int len) { + byte[] bytes = new byte[len]; + for (int i = 0; i < len; i++) { + bytes[i] = mBuffer[mPosition + i]; + } + mPosition += len; + return bytes; + } + + public int Read (byte[] bytes) { + return Read (bytes, 0, bytes.Length); + } + + public int Read (byte[] bytes, int offset, int length) { + for (int i = 0; i < length; i++) { + if (mPosition >= mTail) + return i; + bytes[i + offset] = mBuffer[mPosition]; + mPosition++; + } + + return length; + } + + public void Write (short n) { + if (CanWrite (2)) { + mBuffer[mPosition + 0] = (byte)(n & 0xff); + mBuffer[mPosition + 1] = (byte)((n >> 8) & 0xff); + } + PositionAdd (2); + } + + public void Write (int n) { + if (CanWrite (4)) { + mBuffer[mPosition + 0] = (byte)(n & 0xff); + mBuffer[mPosition + 1] = (byte)((n >> 8) & 0xff); + mBuffer[mPosition + 2] = (byte)((n >> 16) & 0xff); + mBuffer[mPosition + 3] = (byte)((n >> 24) & 0xff); + } + PositionAdd (4); + } + + public void Write (long n) { + if (CanWrite (8)) { + mBuffer[mPosition + 0] = (byte)(n & 0xff); + mBuffer[mPosition + 1] = (byte)((n >> 8) & 0xff); + mBuffer[mPosition + 2] = (byte)((n >> 16) & 0xff); + mBuffer[mPosition + 3] = (byte)((n >> 24) & 0xff); + mBuffer[mPosition + 4] = (byte)((n >> 32) & 0xff); + mBuffer[mPosition + 5] = (byte)((n >> 40) & 0xff); + mBuffer[mPosition + 6] = (byte)((n >> 48) & 0xff); + mBuffer[mPosition + 7] = (byte)((n >> 56) & 0xff); + } + PositionAdd (8); + } + + public void Write (byte b) { + if (CanWrite (1)) { + mBuffer[mPosition] = b; + } + PositionAdd (1); + } + + public void Write (byte[] bytes) { + Write (bytes, 0, bytes.Length); + } + + public void Write (byte[] bytes, int offset, int length) { + if (CanWrite (length)) { + Array.Copy (bytes, offset, mBuffer, mPosition, length); + } + PositionAdd (length); + } + + // NOTE : mPosition can be larger than mLength, but nothing will be wirten if so. + // using this feature to determine size required. + private void PositionAdd (int n) { + mPosition += n; + if (mPosition > mTail) { + mTail = mPosition; + if (mTail > mLength) + mTail = mLength; + } + } + + private bool CanWrite (int n) { + if (mPosition + n > mLength) + { + //Util.Log("SpStream:Warning: Message Size > DEFAULT_SIZE " + DEFAULT_SIZE); + int nLen = mLength * 5 / 4; + if (nLen < mPosition + n) + { + nLen = mPosition + n; + } + byte[] nbuff = new byte[nLen]; + if (null != nbuff) + { + if (mBuffer.Length < mPosition || mPosition < 0 || nbuff.Length < mPosition) + throw new Exception(string.Format("SpStream:Error: mPosition Error: pos={0} buf.len={1} nbuf.len={2}", mPosition, mBuffer.Length, nbuff.Length)); + + Array.Copy(mBuffer, nbuff, mPosition); + mBuffer = nbuff; + mLength = nLen; + } + else + { + //Util.Log("SpStream:Error: allow new buffer FAIL"); + throw new Exception("SpStream:Error: allow new buffer FAIL"); + } + } + return (mPosition + n <= mLength); + } + + public int Position { + get { return mPosition; } + set { mPosition = value; } + } + + public int Offset { get { return mOffset; } } + public int Length { get { return mTail - mOffset; } } + public int Available { get { return mLength - mPosition; } } + public int Capacity { get { return mLength; } } + public int Tail { get { return mTail; } } + public byte[] Buffer { get { return mBuffer; } } + + public void CutTailToPosition() { if (mTail > mPosition) mTail = mPosition; } +} diff --git a/Assets/Scripts/Framework/sproto/src/SpStream.cs.meta b/Assets/Scripts/Framework/sproto/src/SpStream.cs.meta new file mode 100644 index 0000000..58d4079 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpStream.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 62daffc98bca1e64ca79a93d8eca210c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Scripts/Framework/sproto/src/SpStreamCache.cs b/Assets/Scripts/Framework/sproto/src/SpStreamCache.cs new file mode 100644 index 0000000..8df44c1 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpStreamCache.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +class SpStreamCache +{ + const int kSpStreamCacheMax = 10; + static int sSpStreamCacheFreeIdx = -1; + static SpStream[] sSpStreamCache = new SpStream[kSpStreamCacheMax]; + static readonly object sSpStreamCacheLockObj = new object(); + static readonly object sSpStreamCacheLockObj2 = new object(); + + public static SpStream Get() + { + lock (sSpStreamCacheLockObj) + { + if (sSpStreamCacheFreeIdx < 0 || sSpStreamCacheFreeIdx >= sSpStreamCache.Length) + return new SpStream(); + var tmp = sSpStreamCache[sSpStreamCacheFreeIdx]; + sSpStreamCacheFreeIdx--; + return tmp; + } + } + + public static void Collect(SpStream sp) + { + if (sp == null) + return; + lock (sSpStreamCacheLockObj2) + { + int idx = sSpStreamCacheFreeIdx + 1; + if (idx >= 0 && idx < sSpStreamCache.Length) + { + sp.Reset(); + sSpStreamCache[idx] = sp; + sSpStreamCacheFreeIdx = idx; + } + } + } +} + diff --git a/Assets/Scripts/Framework/sproto/src/SpStreamCache.cs.meta b/Assets/Scripts/Framework/sproto/src/SpStreamCache.cs.meta new file mode 100644 index 0000000..10b221a --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpStreamCache.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6e656491dd0f74d439b359b1ca5c785d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Scripts/Framework/sproto/src/SpType.cs b/Assets/Scripts/Framework/sproto/src/SpType.cs new file mode 100644 index 0000000..921e6ec --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpType.cs @@ -0,0 +1,161 @@ +using System.Collections.Generic; +using System; + +[Serializable] +public class SpType { +#if USE_OLD_SPRTYPE + public string Name; + public Dictionary Fields = new Dictionary (); + public Dictionary FieldNames = new Dictionary (); + + public SpType (string name) { + Name = name; + } + + public void AddField (SpField f) { + Fields.Add(f.Tag, f); + FieldNames.Add(f.Name, f); + } + + public SpField GetFieldByName (string name) { + if (FieldNames.ContainsKey(name)) + return FieldNames[name]; + return null; + } + + public SpField GetFieldByTag (int tag) { + if (Fields.ContainsKey(tag)) + return Fields[tag]; + return null; + } + + public bool CheckAndUpdate () { + bool complete = true; + foreach (SpField f in Fields.Values) { + if (f.CheckAndUpdate ()) + continue; + complete = false; + } + return complete; + } +#else + public string Name; + public SpField[] Fields; + protected string[] mFiledsNames = null; + public string[] FiledsNames { get { + if (mFiledsNames != null) + return mFiledsNames; + if (Fields == null || Fields.Length <= 0) + return null; + int count = 0; + for (int i = 0; i < Fields.Length; i++) + if (Fields[i]!=null) + count++; + if (count <= 0) + return null; + int idx = 0; + mFiledsNames = new string[count]; + for (int i = 0; i < Fields.Length; i++) + { + var f = Fields[i]; + if (f != null) + { + mFiledsNames[idx] = f.Name; + idx++; + } + } + + return mFiledsNames; + } } + + public SpType(string name) + { + Name = name; + Fields = null; + } + + public SpType(string name, int len) + { + Name = name; + Fields = new SpField[len]; + System.Array.Clear(Fields, 0, Fields.Length); + } + + public SpType(string name, params SpField[] args) + { + Name = name; + if (args == null || args.Length == 0) + { + Fields = null; + } + else + { + Fields = args; + } + } + + public void AddField(SpField f) + { + int idx = f.Tag; + + if (Fields == null) + { + Fields = new SpField[1]; + System.Array.Clear(Fields, 0, Fields.Length); + } + + if (idx > Fields.Length && idx - Fields.Length > 256) + { + throw new Exception("SpType:AddField f.Tag is Too Large"); + } + + int len = Fields.Length; + if (len <= idx) + { + len = idx + 1; + var newFields = new SpField[len]; + System.Array.Copy(Fields, newFields, Fields.Length); + Fields = newFields; + } + Fields[idx] = f; + } + + public SpField GetFieldByName(string name) + { + if (Fields == null) + return null; + for (int i = 0, count = Fields.Length; i < count; i++) + { + var f = Fields[i]; + if (f == null) + continue; + if (f.Name == name) + return f; + } + return null; + } + + public SpField GetFieldByTag(int tag) + { + if (Fields == null || tag < 0 || tag >= Fields.Length) + return null; + return Fields[tag]; + } + + public bool CheckAndUpdate(SpTypeManager typeManager) + { + if (Fields == null) + return true; + bool complete = true; + foreach (SpField f in Fields) + { + if (f == null) + continue; + if (f.CheckAndUpdate(typeManager)) + continue; + complete = false; + } + return complete; + } +#endif +} diff --git a/Assets/Scripts/Framework/sproto/src/SpType.cs.meta b/Assets/Scripts/Framework/sproto/src/SpType.cs.meta new file mode 100644 index 0000000..a804700 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpType.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eb11fd25fd132274592f371f946edb59 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Scripts/Framework/sproto/src/SpTypeManager.cs b/Assets/Scripts/Framework/sproto/src/SpTypeManager.cs new file mode 100644 index 0000000..309c381 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpTypeManager.cs @@ -0,0 +1,119 @@ +using System.Collections.Generic; +using System.IO; + +public class SpTypeManager : SpProtoParserListener { + private Dictionary mProtocols = new Dictionary (); + private Dictionary mProtocolsByTag = new Dictionary (); + + private Dictionary mTypes = new Dictionary (); + private Dictionary mIncompleteTypes = new Dictionary (); + private SpType mTypeInteger; + private SpType mTypeString; + private SpType mTypeBoolean; + private SpType mTypeBytes; + + private SpCodec mCodec; + + public SpTypeManager () { + mTypeInteger = new SpType ("integer"); + mTypeBoolean = new SpType ("boolean"); + mTypeString = new SpType ("string"); + mTypeBytes = new SpType("bytes"); + + OnNewType (mTypeInteger); + OnNewType (mTypeString); + OnNewType (mTypeBoolean); + OnNewType (mTypeBytes); + + mCodec = new SpCodec (this); + } + + public void OnNewType (SpType type) { + if (GetType (type.Name) != null) + return; + + if (IsTypeComplete (type)) + mTypes.Add (type.Name, type); + else + mIncompleteTypes.Add (type.Name, type); + } + + public void OnNewProtocol (SpProtocol protocol) { + if (GetProtocolByName (protocol.Name) != null || GetProtocolByTag (protocol.Tag) != null) + return; + + mProtocols.Add (protocol.Name, protocol); + mProtocolsByTag.Add (protocol.Tag, protocol); + } + + private bool IsTypeComplete (SpType type) { + return type.CheckAndUpdate (this); + } + + public SpProtocol GetProtocolByName (string name) { + if (mProtocols.ContainsKey (name)) { + return mProtocols[name]; + } + return null; + } + + public SpProtocol GetProtocolByTag (int tag) { + if (mProtocolsByTag.ContainsKey (tag)) { + return mProtocolsByTag[tag]; + } + return null; + } + + public SpType GetType (string name) { + if (mTypes.ContainsKey (name)) { + return mTypes[name]; + } + + if (mIncompleteTypes.ContainsKey (name)) { + SpType t = mIncompleteTypes[name]; + if (IsTypeComplete (t)) { + mIncompleteTypes.Remove (name); + mTypes.Add (name, t); + } + return t; + } + + return null; + } + + public SpType GetTypeNoCheck (string name) { + if (mTypes.ContainsKey (name)) { + return mTypes[name]; + } + + if (mIncompleteTypes.ContainsKey (name)) { + return mIncompleteTypes[name]; + } + + return null; + } + + public bool IsBuildinType (SpType type) { + if (type == mTypeInteger || type == mTypeBoolean || type == mTypeString || type == mTypeBytes) + return true; + return false; + } + + public SpType Integer { get { return mTypeInteger; } } + public SpType String { get { return mTypeString; } } + public SpType Boolean { get { return mTypeBoolean; } } + public SpType Bytes { get { return mTypeBytes; } } + public SpCodec Codec { get { return mCodec; } } + + public static SpTypeManager Import (Stream stream) { + SpTypeManager instance = new SpTypeManager (); + new SpProtoParser (instance).Parse (stream); + return instance; + } + + public static SpTypeManager Import (string proto) { + SpTypeManager instance = new SpTypeManager (); + new SpProtoParser (instance).Parse (proto); + return instance; + } +} diff --git a/Assets/Scripts/Framework/sproto/src/SpTypeManager.cs.meta b/Assets/Scripts/Framework/sproto/src/SpTypeManager.cs.meta new file mode 100644 index 0000000..6931955 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SpTypeManager.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9d0bc4ee48a750b42bd58182c4ee59d5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Scripts/Framework/sproto/src/SprotoUtil.cs b/Assets/Scripts/Framework/sproto/src/SprotoUtil.cs new file mode 100644 index 0000000..8bd9470 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SprotoUtil.cs @@ -0,0 +1,170 @@ +using System.Collections.Generic; +using System.IO; +using System; +using UnityEngine; +using System.Text; + +public class SprotoUtil +{ + public static void DumpStream(SpStream stream) + { + StringBuilder str = new StringBuilder(); + byte[] buf = new byte[16]; + int count; + while ((count = stream.Read(buf, 0, buf.Length)) > 0) + { + str.Append(DumpLine(buf, count)); + } + Log(str.ToString()); + } + + private static string DumpLine(byte[] buf, int count) + { + StringBuilder str = new StringBuilder(); + for (int i = 0; i < count; i++) + { + if (i < count) + str.AppendFormat("{0:X2}", buf[i]); + else + str.Append(" "); + + str.Append((i > 0) && (i < count - 1) && ((i + 1) % 8 == 0) ? " - " : " "); + } + str.AppendLine(); + return str.ToString(); + } + + public static void LogErrorEx(string msg, Exception ex, SpObject obj) + { + + var str = new StringBuilder(); + str.AppendLine(msg); + str.AppendLine(ex.ToString()); + str.AppendLine(ex.StackTrace); + SprotoUtil.DumpObject(obj, 0, str); + GameLogger.LogError(str.ToString()); + + } + + public static void DumpObjectWithMsg(string msg, SpObject obj) + { + var str = new StringBuilder(); + str.Append(msg); + DumpObject(obj, 0, str); + Log(str.ToString()); + } + + public static void DumpObject(SpObject obj) + { + var str = new StringBuilder(); + DumpObject(obj, 0, str); + Log(str.ToString()); + + } + + public static void DumpObject(SpObject obj, int tab, StringBuilder str = null) + { + if (obj != null) + { + if (str == null) + str = new StringBuilder(); + + if (obj.IsTable()) + { + AddTab(str, tab); + str.Append("\n"); + + SpDict d = obj.AsSpDict(); + if (d != null) + { + var values = d.Values; + var ks = d.Keys; + for (int i = 0, count = ks.Length; i < count; i++) + { + string k = ks[i]; + SpObject v = values[i]; + if (v == null) + continue; + AddTab(str, tab + 1); + str.Append("\n"); + DumpObject(v, tab + 1, str); + } + } + else + { + foreach (KeyValuePair entry in obj.AsTable()) + { + AddTab(str, tab + 1); + str.Append("\n"); + DumpObject(entry.Value, tab + 1, str); + } + } + } + else + { + if (obj.IsArray()) + { + AddTab(str, tab); + str.Append("\n"); + foreach (SpObject o in obj.AsArray()) + { + DumpObject(o, tab + 1, str); + } + } + else + { + if (obj.Value == null) + { + AddTab(str, tab); + str.Append("\n"); + } + else + { + AddTab(str, tab); + str.Append(obj.Value.ToString()); + str.Append("\n"); + } + } + } + } + else + { + str.Append("SpObject obj == null"); + } + } + + + private static readonly string[] kAddTabArr = { "\t", "\t\t", "\t\t\t", "\t\t\t\t", "\t\t\t\t\t", "\t\t\t\t\t\t", "\t\t\t\t\t\t" }; + + private static void AddTab(StringBuilder str, int n) + { + if (n > 0 && n <= kAddTabArr.Length) + { + str.Append(kAddTabArr[n - 1]); + return; + } + + for (int i = 0; i < n; i++) + str.Append("\t"); + } + + public static void Log(object obj) + { + GameLogger.Log(obj.ToString()); + } + + public static void Assert(bool condition) + { + if (condition == false) + throw new Exception(); + } + + public static string GetFullPath(string path) + { + return Application.dataPath + "/" + path; + } +} diff --git a/Assets/Scripts/Framework/sproto/src/SprotoUtil.cs.meta b/Assets/Scripts/Framework/sproto/src/SprotoUtil.cs.meta new file mode 100644 index 0000000..28ed105 --- /dev/null +++ b/Assets/Scripts/Framework/sproto/src/SprotoUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1be32c42bada1bd4d9893e4cd0a7dc7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/HOTween.meta b/Assets/Scripts/HOTween.meta new file mode 100644 index 0000000..787d5dc --- /dev/null +++ b/Assets/Scripts/HOTween.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 16e5f5dc255c5c64abbbd7fc70ec7536 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LuaFramework/Scripts/Manager/Interface.meta b/Assets/Scripts/HOTween/Editor.meta similarity index 63% rename from Assets/LuaFramework/Scripts/Manager/Interface.meta rename to Assets/Scripts/HOTween/Editor.meta index 3770a15..2339a2c 100644 --- a/Assets/LuaFramework/Scripts/Manager/Interface.meta +++ b/Assets/Scripts/HOTween/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4654f39cc1fc05b4ca5f272cc65b39a8 +guid: 72ee5062e62d4e544846056c8e728505 folderAsset: yes DefaultImporter: userData: diff --git a/Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll b/Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll new file mode 100644 index 0000000000000000000000000000000000000000..1cbdf199b48115998af5fcb6d5acd9570c1cd85d GIT binary patch literal 12288 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 xsg30`usr^|q)ji@0)nKS2` z?>y$*bMM}rg4fpmQ8?vtRT-s6*U<4D`(H8_yj8mHiZW*6#9bOu0;cgfL>&4>JdcAG zxIKgOfj7f`33_CRI5Gah5YPotAkBeUO@ZpBP{3YgN8^d6P-w{$wGGRCA+x?R7_165 zg=*r__^L=WYQt8uuwk`r$EH;#lXiP^bWKx+SXvsYYKf%c9V0|-ESaz^5Yw#WiZ6DS zUrlVQ9_W2unY}f!`_T#Gwx7AU;POyv`J`||*F$9gKQ#pE>+daNOvP>g^aDrC^~t55 zR_0eNJKr~uSDBczX3~v-^~i6DgB1Rc%P`{|Hu_P$q&ApZ6SdKaKI`EVvkp%(j}CVn z`{h)A=-qF_?-fle+7lkjFSQ=+J5Ee43f6MG$7Kd5&zM|-L0*Ap3S3IL0+$F}Mxz|; zqdW&sr_l~Br+f#`paKWaq%jVzps@~qj2;lU9QjL2Xqh_YhzExlf+!9cuH=A zBq^Sbm9bbP)|z?dMk2g2X}4q^vvRF?dm?J5946b_5=n-eqYj~}>AaM~BBbFZ)gAGb z33BPFa7U}1O25+WZWU~OxY>@9J`!PQsnreA3;URtv+4VuI@jbc>>gX}_nRiMxxDAX zog9TT0l(?la64DYW@b=4?G^@?G+dMhg-L$rUH-d!`Bw$6N&m|kUZi>DE}hP=GOokV z@+n)G?kjJ!e3~`exqRg!=+1eksLj3UqP{FFG$%+YhAy7p*4S++OLSkiuTeyt77^)c zU(ZAY2ivT{vPNH>Ec>Kz@XGQAqywh&jEIzmbmSpv7{xx}*Kh=gRye5*36EqP_{SOh zEM6h!%-E(ZI;b8}(PlLI0Ap5B<4~Zk-d7hO#@KEb?Q!+sK;eqBkxGcNSA>(bEpSMR zsAG&BQCjquMZh~Q`pR_*0Ses{z#NR-M*IY0+Kxg|<6bd4UDkLZGdo+W6Pel1F52kc zD-^o4Z@h{jj~6l9=$gc$oUL5 zuV9W32L829XY^smP>He_zpm2_{iZ|CljKH&HW^(;`rVwHlH6g?PGgrt1|<2WK?jTh zhpdw12L^p;eB_YxB{^)+S>qf?M%hvMt0Kzcyq0wrnPx|usO73bw~b%n@(+uIki|^H z9%X#1hx$Elc>c|OS;qaChlV|8;hsggvmb8_g(9&?sy=Roqb0=dV@gT6k0~R5ALB!N zP)&&S@7=pE)o-=+cUqR!a;txXcC&MXc6_jHsIybldCfy_dk=d@x><~N%;oQk)pN_v z{OF}C-k)H{QLJvuBC5b?j6X_s0Js-|NA)7~X$UTLYBrGu!KJRkZIJ-DwnKM9@IS1c zgzkf2%d0;?pM_wrslP+tf?&nfJOsHQ=(susdLjh3H=0K67D3c(!Z$AtJ0xCId(5zm1X{GYf9p5Z3= HEa<-h{@Dad literal 0 HcmV?d00001 diff --git a/Assets/LuaFramework/Luajit/jit/dis_arm.lua.meta b/Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll.mdb.meta similarity index 56% rename from Assets/LuaFramework/Luajit/jit/dis_arm.lua.meta rename to Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll.mdb.meta index c4f69d0..ffa2281 100644 --- a/Assets/LuaFramework/Luajit/jit/dis_arm.lua.meta +++ b/Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll.mdb.meta @@ -1,4 +1,4 @@ fileFormatVersion: 2 -guid: 4a5d0750f7c50434799a22a9fd01dd11 +guid: 23ccc9c47ecfe004d81eef4056b76b83 DefaultImporter: userData: diff --git a/Assets/LuaFramework/Luajit/lua51.dll.meta b/Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll.meta similarity index 51% rename from Assets/LuaFramework/Luajit/lua51.dll.meta rename to Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll.meta index fcfab03..4803cf4 100644 --- a/Assets/LuaFramework/Luajit/lua51.dll.meta +++ b/Assets/Scripts/HOTween/Editor/HOTweenV1_Editor.dll.meta @@ -1,16 +1,23 @@ fileFormatVersion: 2 -guid: ee6027814429a0a43822294a9a9047a2 -timeCreated: 1498139740 -licenseType: Pro +guid: d9cbebd69f51cb346b3d41b4360911db PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 + isOverridable: 0 platformData: Any: - enabled: 1 + enabled: 0 settings: {} + Editor: + enabled: 1 + settings: + DefaultValueInitialized: true + WindowsStoreApps: + enabled: 0 + settings: + CPU: AnyCPU userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Scripts/HOTween/HOTween.XML b/Assets/Scripts/HOTween/HOTween.XML new file mode 100644 index 0000000..8a3beb6 --- /dev/null +++ b/Assets/Scripts/HOTween/HOTween.XML @@ -0,0 +1,8450 @@ + + + + HOTween + + + + + Plugin for the tweening of the color of your choice. + Used for changing material colors different from the default one (like _SpecColor or _Emission). + Target for this tween must be of type . + + + + + ABSTRACT base class for all classes. + + + + + Untyped start value. + + + + + Untyped end value. + + + + + Stored so it can be set indipendently in case of speed-based tweens. + + + + + Name of the property being tweened. Stored during Init, used by overwrite manager and log messages. + + + + + Stored to be used during recreation of plugin for partial tweens. + + + + + Ease type. + + + + + Indicates that the end value is relative instead than absolute. + Default: false. + + + + + Some plugins (like PlugSetColor) may set this to false when instantiated, + to prevent the creation of a useless valAccessor. + + + + + Reference to the Tweener controlling this plugin. + + + + + Creates a new instance of this plugin with the given options. + Used because easeType can't be null, and otherwise there's no way + to understand if the ease was voluntarily set by the user or not. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin with the given options. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin with the given options. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Initializes the plugin after its instantiation. + Called by Tweener after a property and plugin have been validated, and the plugin has to be set and added. + Virtual because some classes (like PlugVector3Path) override it to avoid isRelative being TRUE. + + + The to refer to. + + + The name of the property to control. + + + The to use. + + + Directly passed from TweenParms to speed up MemberAccessor creation. + + + Directly passed from TweenParms to speed up MemberAccessor creation. + + + Directly passed from TweenParms to speed up MemberAccessor creation. + + + + + Starts up the plugin, getting the actual start and change values. + Called by Tweener right before starting the effective animations. + + + + + Starts up the plugin, getting the actual start and change values. + Called by Tweener right before starting the effective animations. + + + Set to true by , + to calculate only the speed based duration and then reset any startup changes + (so Startup can be called from scratch when truly starting up). + + + + + If speed based duration was not already set (meaning Startup has not yet been called), + calculates the duration and then resets the plugin so that Startup will restart from scratch. + Used by . + + + + + Overridden by plugins that need a specific type of target, to check it and validate it. + Returns true if the tween target is valid. + + + + + Updates the tween. + + + The total elapsed time since startup (loops excluded). + + + + + Updates the plugin. + + + + + Rewinds the tween. + Should be overriden by tweens that control only part of the property (like HOTPluginVector3X). + + + + + Completes the tween. + Should be overriden by tweens that control only part of the property (like HOTPluginVector3X). + + + + + Reverses the ease of this plugin. + + + + + Sets the ease type (called during Init, but can also be called by Tweener to change easeType while playing). + + + + + Returns the speed-based duration based on the given speed. + + + + + Returns a clone of the basic plugin + (as it was at construction, without anything that was set during Init). + + + + + Sets the typed changeVal based on the current startVal and endVal. + Can only be called once, otherwise some typedEndVal (like HOTPluginColor) will be set incorrectly. + + + + + Used by Tweeners to force SetIncremental + (SetIncremental can't be made internal since + it needs to be overridden outside of HOTweem for custom plugin). + + + + + Sets the correct values in case of Incremental loop type. + Also called by Tweener.ApplySequenceIncrement (used by Sequences during Incremental loops). + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Sets the value of the controlled property. + Some plugins (like PlugSetColor or PlugQuaterion) might override this to get values from different properties. + + + The new value. + + + + + Gets the current value of the controlled property. + Some plugins (like PlugSetColor) might override this to set values on different properties. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Used by TweenParms to understand if this plugin was initialized with + another Tweener, and thus clone it. + + + + + Used by to get the property name. + + + + + Some plugins might override this to specify a different ID (like PlugVector3X). + Used by to check if two plugins are the same (for overwrite purposes). + Plugins with -1 ids always overwrite and are overwritten. + Plugins with different ids are always overwritten by plugins with -1 ids, + but overwrite only identical ids. + + + The plugin identifier. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Selects the color property to change. + + + The propertyName/colorName to change (see Unity's if you don't know how it works), + set via the enum. + + + + + Selects the color property to change. + + + The propertyName/colorName to change (see Unity's if you don't know how it works). + + + + + Overridden by plugins that need a specific type of target, to check it and validate it. + Returns true if the tween target is valid. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Sets the value of the controlled property. + Some plugins (like PlugSetColor) might override this to get values from different properties. + + + The new value. + + + + + Gets the current value of the controlled property. + Some plugins (like PlugSetColor) might override this to set values on different properties. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Enumeration of color properties names. + + + + + Main color of a material. + + + + + Specular color of a material (used in specular/glossy/vertexlit shaders). + + + + + Emissive color of a material (used in vertexlit shaders). + + + + + Reflection color of a material (used in reflective shaders). + + + + + Default plugin for the tweening of Vector4 objects. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Tween. + + + Time. + + + Begin value. + + + Change value. + + + Duration. + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + A + + + + + Tween. + + + Time. + + + Begin value. + + + Change value. + + + Duration. + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + A + + + + + Tween. + + + Time. + + + Begin value. + + + Change value. + + + Duration. + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + A + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a sinusoidal (sin(t)) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a sinusoidal (sin(t)) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a sinusoidal (sin(t)) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Plugin for uint values + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Default plugin for the tweening of Vector3 objects. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Public interface shared by and . + + + + + Kills this Tweener/Sequence. + + + + + Resumes this Tweener/Sequence (tween delay included). + + + + + Resumes this Tweener/Sequence (tween delay included) and plays it forward. + + + + + Resumes this Tweener/Sequence and plays it backwards. + + + + + Pauses this Tweener/Sequence. + + + + + Rewinds this Tweener/Sequence (loops and tween delay included), and pauses it. + + + + + Restarts this Tweener/Sequence from the beginning (loops and tween delay included). + + + + + Reverses this Tweener/Sequence, + animating it backwards from its current position. + + + If TRUE, the tween will also start playing in case it was paused, + otherwise it will maintain its current play/pause state (default). + + + + + Completes this Tweener/Sequence. + Where a loop was involved and not infinite, the Tweener/Sequence completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + + + Sends the Tweener/Sequence to the given time (taking also loops into account). + If the time is bigger than the total Tweener/Sequence duration, it goes to the end. + + + The time where the Tweener/Sequence should be sent. + + + Returns true if the Tweener/Sequence reached its end and was completed. + + + + + Sends the Tweener/Sequence to the given time (taking also loops into account) and plays it. + If the time is bigger than the total Tweener/Sequence duration, it goes to the end. + + + The time where the Tweener/Sequence should be sent. + + + Returns true if the Tweener/Sequence reached its end and was completed. + + + + + A coroutine that waits until the Tweener/Sequence is complete (delays and loops included). + You can use it inside a coroutin as a yield. Ex: + yield return StartCoroutine( myTweenComponent.WaitForCompletion() ); + + + + + A coroutine that waits until the Tweener/Sequence is rewinded (loops included). + You can use it inside a coroutine as a yield. Ex: + yield return StartCoroutine( myTweenComponent.WaitForRewind() ); + + + + + Assigns the given callback to this Tweener/Sequence, + overwriting any existing callbacks of the same type. + + The type of callback to apply + The function to call, who must return void and accept no parameters + + + + Assigns the given callback to this Tweener/Sequence, + overwriting any existing callbacks of the same type. + + The type of callback to apply + The function to call, who must return void and accept no parameters. + It must return void and has to accept a single parameter of type + Additional comma separated parameters to pass to the function + + + + Returns true if the given target is currently involved in this Tweener/Sequence (taking into account also nested tweens). + Returns false both if the given target is not inside this Tweener/Sequence, than if the relative Tweener/Sequence is paused. + To simply check if the target is attached to this Tweener/Sequence, use IsLinkedTo( target ) instead. + + + The target to check. + + + A value of true if the given target is currently involved in a running tween or sequence. + + + + + Returns true if the given target is linked to this Tweener/Sequence (running or not, taking into account also nested tweens). + + + The target to check. + + + A value of true if the given target is linked to this Tweener/Sequence (running or not, taking into account also nested tweens). + + + + + Eventual ID of this tween + (more than one tween can share the same ID, thus allowing for grouped operations). + You can also use intId instead of id for faster operations. + + + + + Default is -1. + Eventual int ID of this tween + (more than one tween can share the same intId, thus allowing for grouped operations). + The main difference from id is that while id is more legible, intId allows for faster operations. + + + + + Default is true. + If false doesn't remove this Tweener/Sequence from HOTween's list when it is completed + (useful if you want to be able to control it independently with GoTo, instead than letting it run), + and you will need to call an HOTween.Kill to remove this Tweener/Sequence. + + + + + Default is true. + If set to false, this Tweener/Sequence will not be updated, + and any use of animation methods (Play/Pause/Rewind/etc) will be ignored + (both if called directly via this instance, than if using HOTween.Play/Pause/Rewind/etc.). + + + + + Time scale that will be used by this Tweener/Sequence. + + + + + Number of times the Tweener/Sequence will run (-1 means the tween has infinite loops, 1 means the tween will run only once). + + + + + Type of loop for this Tweener/Sequence, in case is greater than 1 (or infinite). + + + + + Gets and sets the time position of the Tweener/Sequence (loops are included when not infinite, delay is not). + + + + + Duration of this Tweener/Sequence, loops and tween delay excluded. + + + + + Full duration of this Tweener/Sequence, loops included (when not infinite) but tween delay excluded. + + + + + Elapsed time within the current loop (tween delay excluded). + Note that elapsed will be equal to duration only when all the loops are completed, + otherwise each time a loop is completed, completedLoops is augmented by 1 and elapsed is reset to 0. + + + + + Full elapsed time including loops (but without considering tween delay). + + + + + The update type for this Tweener/Sequence. + + + + + Number of loops that have been executed. + + + + + Returns a value of true if this Tweener/Sequence contains no tweens + (if this is a Tweener, it means that no valid property to tween was set; + if this is a Sequence, it means no valid was added). + + + + + Returns a value of true if this Tweener/Sequence is set to go backwards (because of a call to Reverse. + + + + + Returns a value of true when this Tweener/Sequence is in the "going backwards" part of a Yoyo loop. + + + + + Returns a value of true if this Tweener/Sequence is paused. + + + + + Returns a value of true after this Tweener/Sequence was started the first time, + or if a call to GoTo or GoToAndPlay was executed. + + + + + Returns a value of true when this Tweener/Sequence is complete. + + + + + Returns a value of true if this Tweener/Sequence was added to a Sequence. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for an exponential (2^t) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for an exponential (2^t) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for an exponential (2^t) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Base class for all HOTween members + ( and ). + + + + + Always set to TRUE by Update(), if isStartupIteration is true, + and reset to FALSE in the last line of Update(). + Can also be set to TRUE by Sequence.TweenStartupIteration, + and then immediately reset to FALSE. + + + + + Used by main Sequences to set an ignoreCallbacks value to all its items/subitems, + which the items/subitmes themselves won't be able to reset. + Necessary during TweenStartupIteration. + + + + + Completed loops. + + + + + Duration. + + + + + Memorized when a partial tween is applied. + + + + + Memorized when applying speedBased duration. + + + + + Full duration. + + + + + Elapsed. + + + + + Full elapsed. + + + + + Destroyed. + + + + + Is empty. + + + + + Running backwards. + + + + + Yoyo looping back. + + + + + Has started. + + + + + Is complete. + + + + + Used to determine if OnUpdate callbacks should be called. + Refreshed at the end of each update. + + + + + Previously completed loops. + Refrehsed at the end of each update. + + + + + True if there are behaviours to manage + + + + + True if there are gameObject to manage + + + + + Behaviours to activate + + + + + Behaviours to deactivate + + + + + GameObjects to activate + + + + + GameObejcts to deactivate + + + + + True = enabled, False = disabled + + + + + True = active, False = inactive + + + + + Kills this Tweener/Sequence, removes it from HOTween, and cleans it. + + + + + Kills this Tweener/Sequence and cleans it. + + + If true also calls HOTween.Kill(this) to remove it from HOTween. + Set internally to false when I already know that HOTween is going to remove it. + + + + + Resumes this Tweener/Sequence (tween delay included). + + + + + Resumes this Tweener/Sequence (tween delay included) and plays it forward. + + + + + Resumes this Tweener/Sequence and plays it backwards. + + + + + Pauses this Tweener/Sequence. + + + + + Rewinds this Tweener/Sequence (loops and tween delay included), and pauses it. + + + + + Restarts this Tweener/Sequence from the beginning (loops and tween delay included). + + + + + Reverses this Tweener/Sequence, + animating it backwards from its curren position. + + + If TRUE, the tween will also start playing in case it was paused, + otherwise it will maintain its current play/pause state (default). + + + + + Completes this Tweener/Sequence. + Where a loop was involved, the Tweener/Sequence completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + + + Sends the Tweener/Sequence to the given time (taking also loops into account). + If the time is bigger than the total Tweener/Sequence duration, it goes to the end. + + + The time where the Tweener/Sequence should be sent. + + + Returns true if the Tweener/Sequence reached its end and was completed. + + + + + Sends the Tweener/Sequence to the given time (taking also loops into account). + If the time is bigger than the total Tweener/Sequence duration, it goes to the end. + + + The time where the Tweener/Sequence should be sent. + + + By default, if a Tweener/Sequence is already at the exact given time, it will not be refreshed. + Setting this to true will force it to refresh + (useful only if you want to be sure that any changes you made to the tweened property, + outside of HOTween, are reset). + + + Returns true if the Tweener/Sequence reached its end and was completed. + + + + + Sends the Tweener/Sequence to the given time (taking also loops into account) and plays it. + If the time is bigger than the total Tweener/Sequence duration, it goes to the end. + + + The time where the Tweener/Sequence should be sent. + + + Returns true if the Tweener/Sequence reached its end and was completed. + + + + + Sends the Tweener/Sequence to the given time (taking also loops into account) and plays it. + If the time is bigger than the total Tweener/Sequence duration, it goes to the end. + + + The time where the Tweener/Sequence should be sent. + + + By default, if a Tweener/Sequence is already at the exact given time, it will not be refreshed. + Setting this to true will force it to refresh + (useful only if you want to be sure that any changes you made to the tweened property, + outside of HOTween, are reset). + + + Returns true if the Tweener/Sequence reached its end and was completed. + + + + + A coroutine that waits until the Tweener/Sequence is complete (delays and loops included). + You can use it inside a coroutine as a yield. Ex: + yield return StartCoroutine( myTweenComponent.WaitForCompletion() ); + + + + + A coroutine that waits until the Tweener/Sequence is rewinded (loops included). + You can use it inside a coroutine as a yield. Ex: + yield return StartCoroutine( myTweenComponent.WaitForRewind() ); + + + + + Completely resets this tween, except its target (in case of Tweeners). + + + + + Assigns the given callback to this Tweener/Sequence, + overwriting any existing callbacks of the same type. + + The type of callback to apply + The function to call, who must return void and accept no parameters + + + + Assigns the given callback to this Tweener/Sequence, + overwriting any existing callbacks of the same type. + + The type of callback to apply + The function to call. + It must return void and has to accept a single parameter of type + Additional comma separated parameters to pass to the function + + + + Assigns the given callback to this Tweener/Sequence, + overwriting any existing callbacks of the same type. + This overload will use sendMessage to call the method named p_methodName + on every MonoBehaviour in the p_sendMessageTarget GameObject. + + The type of callback to apply + GameObject to target for sendMessage + Name of the method to call + Eventual additional parameter + SendMessageOptions + + + + Assigns the given callback to this Tweener/Sequence, + overwriting any existing callbacks of the same type. + + + + + Returns true if the given target is currently involved in a running tween or sequence. + Returns false both if the given target is not inside a tween, than if the relative tween is paused. + To simply check if the target is attached to a tween or sequence, use IsLinkedTo( target ) instead. + + + The target to check. + + + A value of true if the given target is currently involved in a running tween or sequence. + + + + + Returns true if the tween with the given string id is currently involved in a running tween or sequence. + + + The id to check for. + + + + + Returns true if the tween with the given int id is currently involved in a running tween or sequence. + + + The id to check for. + + + + + Returns true if the given target is linked to a tween or sequence (running or not). + + + The target to check. + + + A value of true if the given target is linked to a tween or sequence (running or not). + + + + + Returns a list of all the targets of this tween, or NULL if there are none. + + A list of all the targets of this tween, or NULL if there are none. + + + + Returns a list of the eventual existing tweens with the given Id within this ABSTweenComponent, + nested tweens included (or an empty list if no tweens were found). + + + + + Returns a list of the eventual existing tweens with the given intId within this ABSTweenComponent, + nested tweens included (or an empty list if no tweens were found). + + + + + Used internally by HOTween, to avoid having the tween calling a kill while HOTween will already be killing it. + + + + + Updates the Tweener/Sequence by the given elapsed time, + and returns a value of true if the Tweener/Sequence is complete. + + + The elapsed time since the last update. + + + A value of true if the tween is not reversed and is complete (or the tween target doesn't exist anymore), otherwise false. + + + + + Updates the Tweener/Sequence by the given elapsed time, + and returns a value of true if the Tweener/Sequence is complete. + + + The elapsed time since the last update. + + + If true forces the update even if the Tweener/Sequence is complete or paused, + but ignores onUpdate, and sends onComplete and onStepComplete calls only if the Tweener/Sequence wasn't complete before this call. + + + A value of true if the tween is not reversed and complete (or the tween target doesn't exist anymore), otherwise false. + + + + + Updates the Tweener/Sequence by the given elapsed time, + and returns a value of true if the Tweener/Sequence is complete. + + + The elapsed time since the last update. + + + If true forces the update even if the Tweener/Sequence is complete or paused, + but ignores onUpdate, and sends onComplete and onStepComplete calls only if the Tweener/Sequence wasn't complete before this call. + + + If true means the update is due to a startup iteration (managed by Sequence Startup), + and all callbacks will be ignored. + + + A value of true if the tween is not reversed and complete (or the tween target doesn't exist anymore), otherwise false. + + + + + Updates the Tweener/Sequence by the given elapsed time, + and returns a value of true if the Tweener/Sequence is complete. + + + The elapsed time since the last update. + + + If true forces the update even if the Tweener/Sequence is complete or paused, + but ignores onUpdate, and sends onComplete and onStepComplete calls only if the Tweener/Sequence wasn't complete before this call. + + + If true means the update is due to a startup iteration (managed by Sequence Startup), + and all callbacks will be ignored. + + + If true doesn't call any callback method. + + + A value of true if the tween is not reversed and complete (or the tween target doesn't exist anymore), otherwise false. + + + + + Applies the correct Incremental Sequence loop value. + Called by Sequences when they need to change the increment value of nested Sequences/Tweeners. + + + The difference from the previous main Sequence loop increment. + + + + + Sends the Tweener/Sequence to the given time (taking also loops into account) and plays it. + If the time is bigger than the total Tweener/Sequence duration, it goes to the end. + + + + + Startup this tween + (might or might not call OnStart, depending if the tween is in a Sequence or not). + Can be executed only once per tween. + + + + + Manages on first start behaviour. + + + + + Manages on update behaviour. + + + + + Manages on plugin results behaviour. + + + + + Manages on pause behaviour. + + + + + Manages on resume behaviour (also called when the tween starts). + + + + + Manages on rewinded behaviour. + + + + + Manages step on complete behaviour. + + + + + Manages on complete behaviour. + + + + + Called by HOTween if this tween was placed inside its onCompletes list during this.OnComplete(). + + + + + Sets the current fullDuration, based on the current duration and loops values. + Remember to call this method each time you change the duration or loops of a tween. + + + + + Sets the current elapsed time, based on the current fullElapsed and completedLoops values. + Remember to call this method each time you set fullElapsed (after changing the eventual loops count where needed). + + + + + Sets completedLoops and isLoopingBack, based on the current fullElapsed value. + + + + + Manages the components/gameObjects that should be activated/deactivated. + + + + + Fills the given list with all the plugins inside this sequence tween, + while also looking for them recursively through inner sequences. + Used by HOTween.GetPlugins. + + + + + Eventual string ID of this Tweener/Sequence + (more than one Tweener/Sequence can share the same ID, thus allowing for grouped operations). + You can also use intId instead of id for faster operations. + + + + + Eventual int ID of this Tweener/Sequence + (more than one Tweener/Sequence can share the same intId, thus allowing for grouped operations). + The main difference from id is that while id is more legible, intId allows for faster operations. + + + + + Default is true, which means this Tweener/Sequence will be killed and removed from HOTween as soon as it's completed. + If false doesn't remove this Tweener/Sequence from HOTween when it is completed, + and you will need to call an HOTween.Kill to remove this Tweener/Sequence. + + + + + Default is true. + If set to false, this Tweener/Sequence will not be updated, + and any use of animation methods (Play/Pause/Rewind/etc) will be ignored + (both if called directly via this instance, than if using HOTween.Play/Pause/Rewind/etc.). + + + + + Time scale that will be used by this Tweener/Sequence. + + + + + Number of times the Tweener/Sequence will run (-1 means the tween has infinite loops). + + + + + Type of loop for this Tweener/Sequence, in case is greater than 1 (or infinite). + + + + + Gets and sets the time position of the Tweener/Sequence (loops are included when not infinite, delay is not). + + + + + Duration of this Tweener/Sequence, loops and tween delay excluded. + + + + + Full duration of this Tweener/Sequence, loops included (when not infinite) but tween delay excluded. + + + + + Elapsed time within the current loop (tween delay excluded). + + + + + Full elapsed time including loops (but without considering tween delay). + + + + + The update type for this Tweener/Sequence. + + + + + Number of loops that have been executed. + + + + + Returns a value of true if this Tweener/Sequence was destroyed + (either because it was manually destroyed, because it was completed, or because its target was destroyed). + + + + + Returns a value of true if this Tweener/Sequence contains no tweens + (if this is a tween, it means that no valid property to tween was set; + if this is a sequence, it means no valid was yet added). + + + + + Returns a value of true if this Tweener/Sequence is set to go backwards (because of a call to Reverse. + + + + + Returns a value of true when this Tweener/Sequence is in the "going backwards" part of a Yoyo loop. + + + + + Returns a value of true if this Tweener/Sequence is paused. + + + + + Returns a value of true after this Tweener/Sequence was started the first time, + or if a call to GoTo or GoToAndPlay was executed. + + + + + Returns a value of true when this Tweener/Sequence is complete. + + + + + Returns a value of true if this Tweener/Sequence was added to a Sequence. + + + + + Default plugin for the tweening of Vector2 objects. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Tween type + + + + + Tween to value + + + + + Tween from value + + + + + Sequence component. Manager for sequence of Tweeners or other nested Sequences. + Author: LXFDaniele Giardini (http://www.holoville.com) + + + + + Creates a new Sequence without any parameter. + + + + + Creates a new Sequence. + + + A representing the Sequence parameters. + You can pass an existing one, or create a new one inline via method chaining, + like new SequenceParms().Id("sequence1").Loops(2).OnComplete(myFunction) + + + + Appends the given callback to this Sequence. + The function to call, who must return void and accept no parameters + + + Appends the given callback to this Sequence. + The function to call. + It must return void and has to accept a single parameter of type + Additional comma separated parameters to pass to the function + + + Appends the given SendMessage callback to this Sequence. + GameObject to target for sendMessage + Name of the method to call + Eventual additional parameter + SendMessageOptions + + + Inserts the given callback at the given time position. + Time position where this callback will be placed + (if longer than the whole sequence duration, the callback will never be called) + The function to call, who must return void and accept no parameters + + + Inserts the given callback at the given time position. + Time position where this callback will be placed + (if longer than the whole sequence duration, the callback will never be called) + The function to call. + It must return void and has to accept a single parameter of type + Additional comma separated parameters to pass to the function + + + Inserts the given SendMessage callback at the given time position. + Time position where this callback will be placed + (if longer than the whole sequence duration, the callback will never be called) + GameObject to target for sendMessage + Name of the method to call + Eventual additional parameter + SendMessageOptions + + + + Appends an interval to the right of the sequence, + and returns the new Sequence total time length (loops excluded). + + + The duration of the interval. + + + The new Sequence total time length (loops excluded). + + + + + Adds the given to the right of the sequence, + and returns the new Sequence total time length (loops excluded). + + + The to append. + + + The new Sequence total time length (loops excluded). + + + + + Prepends an interval to the left of the sequence, + and returns the new Sequence total time length (loops excluded). + + + The duration of the interval. + + + The new Sequence total time length (loops excluded). + + + + + Adds the given to the left of the sequence, + moving all the existing sequence elements to the right, + and returns the new Sequence total time length (loops excluded). + + + The to prepend. + + + The new Sequence total time length (loops excluded). + + + + + Inserts the given at the given time, + and returns the new Sequence total time length (loops excluded). + + + The time at which the element must be placed. + + + The to insert. + + + The new Sequence total time length (loops excluded). + + + + + Clears this sequence and resets its parameters, so it can be re-used. + You can check if a Sequence is clean by querying its isEmpty property. + + + New parameters for the Sequence + (if NULL, note that the dafult ones will be used, and not the previous ones) + + + + + Kills this Sequence and cleans it. + + + If true also calls HOTween.Kill(this) to remove it from HOTween. + Set internally to false when I already know that HOTween is going to remove it. + + + + + Rewinds this Sequence (loops included), and pauses it. + + + + + Restarts this Sequence from the beginning (loops included). + + + + + Returns true if the given target is currently involved in a running tween of this Sequence (taking into account also nested tweens). + Returns false both if the given target is not inside any of this Sequence tweens, than if the relative tween is paused. + To simply check if the target is attached to a tween of this Sequence, use IsLinkedTo( target ) instead. + + + The target to check. + + + + + Returns true if the tween with the given string id is currently involved in a running tween or sequence. + + + The id to check for. + + + + + Returns true if the tween with the given int id is currently involved in a running tween or sequence. + + + The id to check for. + + + + + Returns true if the given target is linked to a tween of this Sequence (running or not, taking into account also nested tweens). + + + The target to check. + + + A value of true if the given target is linked to a tween of this Sequence (running or not, taking into account also nested tweens). + + + + + Returns a list of all the targets of this Sequence, or NULL if there are none. + + A list of all the targets of this Sequence, or NULL if there are none. + + + + Returns a list of the eventual nested objects whose target is the given one, + or an empty list if none was found. + + + + + Returns a list of the eventual existing tweens with the given Id within this Sequence, + nested tweens included (or an empty list if no tweens were found). + + + + + Returns a list of the eventual existing tweens with the given Id within this Sequence, + nested tweens included (or an empty list if no tweens were found). + + + + + Removes the given tween from this Sequence, + and eventually kills the Sequence if all items have been removed. + Used by to remove overwritten tweens. + + + + + Completes this Sequence. + Where a loop was involved, the Sequence completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + + + Updates the Sequence by the given elapsed time, + and returns a value of true if the Sequence is complete. + + + The elapsed time since the last update. + + + If true forces the update even if the Sequence is complete or paused, + but ignores onUpdate, and sends onComplete and onStepComplete calls only if the Sequence wasn't complete before this call. + + + If true means the update is due to a startup iteration (managed by Sequence Startup), + and all callbacks will be ignored. + + + If true doesn't call any callback method. + + + A value of true if the Sequence is not reversed and is complete (or all the Sequence tween targets don't exist anymore), otherwise false. + + + + + Sets the correct values in case of Incremental loop type. + Also called by Tweener.ApplySequenceIncrement (used by Sequences during Incremental loops). + + + The difference from the previous loop increment. + + + + + Sends the sequence to the given time (taking also loops into account) and eventually plays it. + If the time is bigger than the total sequence duration, it goes to the end. + + + Returns true if the sequence reached its end and was completed. + + + + + Iterates through all the elements in order, to startup the plugins correctly. + Called at OnStart and during Append/Insert/Prepend for speedBased tweens (to calculate correct duration). + + + + + If the given is a speedBased , + forces it to calculate the correct duration. + + + + + Startup this tween + (might or might not call OnStart, depending if the tween is in a Sequence or not). + Can be executed only once per tween. + + + + + Fills the given list with all the plugins inside this sequence tween, + while also looking for them recursively through inner sequences. + Used by HOTween.GetPlugins. + + + + + Single sequencer item. + Tween value can be null (in case this is simply used as a spacer). + + + + + Default plugin for the tweening of number values. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Enumeration of ease types. + + + + + Linear. + + + + + Ease in sine. + + + + + Ease out sine. + + + + + Ease in out sine. + + + + + Ease in quad. + + + + + Ease out quad. + + + + + Ease in out quad. + + + + + Ease in cubic. + + + + + Ease out cubic. + + + + + Ease in out cubic. + + + + + Ease in quart. + + + + + Ease out quart. + + + + + Ease in out quart. + + + + + Ease in quint. + + + + + Ease out quint. + + + + + Ease in out quint. + + + + + Ease in expo. + + + + + Ease out expo. + + + + + Ease in out expo. + + + + + Ease in circ. + + + + + Ease out circ. + + + + + Ease in out circ. + + + + + Ease in elastic. + + + + + Ease out elastic. + + + + + Ease in out elastic. + + + + + Ease in back. + + + + + Ease out back. + + + + + Ease in out back. + + + + + Ease in bounce. + + + + + Ease out bounce. + + + + + Ease in out bounce. + + + + + Don't assign this! It's assigned internally when setting the ease to an AnimationCurve + + + + + Ease in strong. + OBSOLETE: use EaseInQuint instead. + + + + + OBSOLETE: use EaseOutQuint instead. + Ease out strong. + + + + + OBSOLETE: use EaseInOutQuint instead. + Ease in out strong. + + + + + Enumeration of ease types. + + + + + Ease function. + + + + + Inverse ease function. + + + + + Creates a new instance. + + + The ease function. + + + Inverse ease function. + + + + + Returns an instance based on the given . + + + An . + + + + + Plugin for the tweening of only the Z value of Vector3 objects. + + + + + Plugin for the tweening of only the X value of Vector3 objects. + + + + + Start val. + + + + + End val. + + + + + Change val. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Rewinds the tween. + Should be overriden by tweens that control only part of the property (like HOTPluginVector3X). + + + + + Completes the tween. + Should be overriden by tweens that control only part of the property (like HOTPluginVector3X). + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Rewinds the tween. + Should be overriden by tweens that control only part of the property (like HOTPluginVector3X). + + + + + Completes the tween. + Should be overriden by tweens that control only part of the property (like HOTPluginVector3X). + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Various utils used by HOTween. + + + + + Converts the given Matrix4x4 to a Quaternion and returns it. + + + The matrix to convert. + + + The resulting . + + + + + Returns a string representing the given Type without the packages + (like Single instead than System.Single). + + + + + Returns the 2D angle between two vectors + + + + + Used by and HOTweenInspector, + to store info about tweens that can be displayed. + + + + + Tween. + + + + + Is sequence. + + + + + Targets. + + + + + Creates a new TweenInfo object. + + + + + Is paused. + + + + + Is complete. + + + + + Is enabled. + + + + + PropertyAccessorException class. + + + + + The IMemberAccessor interface defines a member + accessor. + + + + + Gets the value stored in the member for + the specified target. + + Object to retrieve + the member from. + Member value. + + + + Sets the value for the member of + the specified target. + + Object to set the + member on. + Member value. + + + + Creates a new member accessor. + + Member + + + + Added by Daniele Giardini for HOTween, + because if a Make is called we already know that a PropertyInfo or FieldInfo exist, + and we can directly pass them as parameters. + + + + + Thanks to Ben Ratzlaff for this snippet of code + http://www.codeproject.com/cs/miscctrl/CustomPropGrid.asp + + "Initialize a private hashtable with type-opCode pairs + so i dont have to write a long if/else statement when outputting msil" + + + + + Gets the member value from the specified target. + + Target object. + Member value. + + + + Sets the member for the specified target. + + Target object. + Value to set. + + + + This method generates creates a new assembly containing + the Type that will provide dynamic access. + + + + + Create an assembly that will provide the get and set methods. + + + + + Whether or not the Member supports read access. + + + + + Whether or not the Member supports write access. + + + + + The Type of object this member accessor was + created for. + + + + + The Type of the Member being accessed. + + + + + Used to interpret AnimationCurves as eases. + + + + + Plugin for the tweening of only the Y value of Vector3 objects. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Rewinds the tween. + Should be overriden by tweens that control only part of the property (like HOTPluginVector3X). + + + + + Completes the tween. + Should be overriden by tweens that control only part of the property (like HOTPluginVector3X). + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a quartic (t^4) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a quartic (t^4) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a quartic (t^4) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Default plugin for the tweening of Color objects. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for an elastic (exponentially decaying sine wave) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + The eased value. + + + + + Easing equation function for an elastic (exponentially decaying sine wave) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + Amplitude. + + + Period. + + + The eased value. + + + + + Easing equation function for an elastic (exponentially decaying sine wave) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + The eased value. + + + + + Easing equation function for an elastic (exponentially decaying sine wave) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + Amplitude. + + + Period. + + + The eased value. + + + + + Easing equation function for an elastic (exponentially decaying sine wave) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + The eased value. + + + + + Easing equation function for an elastic (exponentially decaying sine wave) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + Amplitude. + + + Period. + + + The eased value. + + + + + Enumeration of the levels of warning that should be used to output messages in case of auto-resolved errors. + + + + + No messages will be logged. + + + + + Only important messages will be logged + (this will exclude warnings when a tween is overwritten). + + + + + All messages will be logged. + + + + + Enumeration of types of update that can be applied to a tween. + + + + + Normal update. + + + + + Late update. + + + + + Fixed update (useful for rigidBodies). + + + + + Timescale independent update. + Contrary to the other types, this one is not subject to changes in Time.timeScale, + thus it's the best way for tweens that happen inside GUI methods + (so that even if the game is paused, the GUI will still have animated tweens). + + + + + This object is passed as the only parameter of all HOTween's callbacks. + + + + + A reference to the IHOTweenComponent that invoked the callback method. + + + + + An array of eventual parameters that were passed to the callback. + + + + + The plugin (if any) that triggered the callback. + + + + + Plugin for the tweening of strings. + + + + + Creates a new instance of this plugin using the main ease type, + substituting any existing string with the given one over time. + + + The value to tween to. + + + + + Creates a new instance of this plugin, + substituting any existing string with the given one over time. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given value will be added to any existing string, + if false the existing string will be completely overwritten. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given value will be added to any existing string, + if false the existing string will be completely overwritten. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + HOTweenException class. + A new HOTweenException is thrown each time HOTween encounters an error. + + + + + Creates a new HOTweenException with the given message. + + + The exception message. + + + + + The PropertyAccessor class provides fast dynamic access + to a property of a specified target class. + + + + + Creates a new property accessor. + + + + + The Type of the Property being accessed. + + + + + Whether or not the Property supports read access. + + + + + Whether or not the Property supports write access. + + + + + Tween component, created by HOTween for each separate tween. + Author: LXFDaniele Giardini (http://www.holoville.com) + + + + + Called by HOTween each time a new tween is generated via To or similar methods. + + + + + Kills this Tweener and cleans it. + + + If true also calls HOTween.Kill(this) to remove it from HOTween. + Set internally to false when I already know that HOTween is going to remove it. + + + + + Resumes this Tweener. + + + If true skips any initial delay. + + + + + Resumes this Tweener and plays it forward. + + + If true skips any initial delay. + + + + + Rewinds this Tweener (loops and tween delay included), and pauses it. + + + + + Rewinds this Tweener (loops included), and pauses it. + + + If true skips any initial delay. + + + + + Restarts this Tweener from the beginning (loops and tween delay included). + + + + + Restarts this Tweener from the beginning (loops and tween delay included). + + + If true skips any initial delay. + + + + + Restarts the tween from position 0, but takes the current target value as start value, + and diffs to find the change value (as if it was a relative tween). + + + + + Completes this Tweener. + Where a loop was involved, the Tweener completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + + + Completely resets the Tweener except its target, + and applies a new , duration, and . + + New tween type (to/from) + New duration + New parameters + + + + Completely resets this Tweener, except its target + + + + + Assigns the given callback to this Tweener/Sequence, + overwriting any existing callbacks of the same type. + + + + + Returns true if the given target and this Tweener target are the same, and the Tweener is running. + Returns false both if the given target is not the same as this Tweener's, than if this Tweener is paused. + This method is here to uniform with . + + + The target to check. + + + + + Returns true if the tween with the given string id is currently involved in a running tween or sequence. + This method is here to uniform with . + + + The id to check for. + + + + + Returns true if the tween with the given int id is currently involved in a running tween or sequence. + This method is here to uniform with . + + + The id to check for. + + + + + Returns true if the given target and this Tweener target are the same. + This method is here to uniform with . + + + The target to check. + + + A value of true if the given target and this Tweener target are the same. + + + + + Returns a list containing the target of this tween. + + A list containing the target of this tween. + + + + Returns a list containing this tween if the id is the same as the given one + (or and empty list if no tweens were found). + + + + + Returns a list containing this tween if the id is the same as the given one + (or and empty list if no tweens were found). + + + + + If this Tweener contains a tween, + returns a point on the path at the given percentage (0 to 1). + Returns a zero Vector if there's no path tween associated with this tween. + Note that, if the tween wasn't started, the OnStart callback will be called + the first time you call this method, because the tween needs to be initialized. + + The percentage (0 to 1) at which to get the point + + + + If this Tweener contains a tween returns the length of the path, + otherwise returns -1 + + + + If this Tweener contains a tween, + defines a portion of that path to use and re-adapt to (easing included), + also re-adapting the duration to the correct partial, + and rewinds/restarts the tween in its partial form (depending if it was paused or not). + + + Id of the new starting waypoint on the current path. + If you want to be sure you're targeting the first point in the path, pass -1 + (this is because the first waypoint of the path might be different from the first waypoint you passed, + in case the target Transform was not already on the starting position, and thus needed to reach it). + + Id of the new ending waypoint on the current path + + + + If this Tweener contains a tween, + defines a portion of that path to use and re-adapt to (easing included), + and rewinds/restarts the tween in its partial form (depending if it was paused or not). + + + Id of the new starting waypoint on the current path. + If you want to be sure you're targeting the first point in the path, pass -1 + (this is because the first waypoint of the path might be different from the first waypoint you passed, + in case the target Transform was not already on the starting position, and thus needed to reach it). + + Id of the new ending waypoint on the current path + + Tween duration of the partial path (if -1 auto-calculates the correct partial based on the original duration) + + + + + If this Tweener contains a tween, + defines a portion of that path to use and re-adapt to (easing included), + and rewinds/restarts the tween in its partial form (depending if it was paused or not). + + + Id of the new starting waypoint on the current path. + If you want to be sure you're targeting the first point in the path, pass -1 + (this is because the first waypoint of the path might be different from the first waypoint you passed, + in case the target Transform was not already on the starting position, and thus needed to reach it). + + Id of the new ending waypoint on the current path + New EaseType to apply + + + + If this Tweener contains a tween, + defines a portion of that path to use and re-adapt to, + and rewinds/restarts the tween in its partial form (depending if it was paused or not). + + + Id of the new starting waypoint on the current path. + If you want to be sure you're targeting the first point in the path, pass -1 + (this is because the first waypoint of the path might be different from the first waypoint you passed, + in case the target Transform was not already on the starting position, and thus needed to reach it). + + + Id of the new ending waypoint on the current path + (-1 in case you want to target the ending waypoint of a closed path) + + + Tween duration of the partial path (if -1 auto-calculates the correct partial based on the original duration) + + New EaseType to apply + + + + If this Tweener contains a tween + that had been partialized, returns it to its original size, easing, and duration, + and rewinds/restarts the tween in its partial form (depending if it was paused or not). + + + + + If this Tweener contains a , returns it. + Otherwise returns null. + + + + + + Updates the Tweener by the given elapsed time, + and returns a value of true if the Tweener is complete. + + + The elapsed time since the last update. + + + If true forces the update even if the Tweener is complete or paused, + but ignores onUpdate, and sends onComplete and onStepComplete calls only if the Tweener wasn't complete before this call. + + + If true means the update is due to a startup iteration (managed by Sequence Startup or HOTween.From), + and all callbacks will be ignored. + + + If true doesn't call any callback method. + + + If true uses p_shortElapsed fully ignoring the delay + (useful when setting the initial FROM state). + + + A value of true if the Tweener is not reversed and is complete (or the tween target doesn't exist anymore), otherwise false. + + + + + Sets the correct values in case of Incremental loop type. + Also called by Tweener.ApplySequenceIncrement (used by Sequences during Incremental loops). + + + The difference from the previous loop increment. + + + + + If speed based duration was not already set (meaning OnStart has not yet been called), + calculates the duration and then resets the tween so that OnStart can be called from scratch. + Used by Sequences when Appending/Prepending/Inserting speed based tweens. + + + + + Sends the tween to the given time (taking also loops into account) and eventually plays it. + If the time is bigger than the total tween duration, it goes to the end. + + + Returns true if the tween reached its end and was completed. + + + + + Startup this tween + (might or might not call OnStart, depending if the tween is in a Sequence or not). + Can be executed only once per tween. + + + + + Startup this tween + (might or might not call OnStart, depending if the tween is in a Sequence or not). + Can be executed only once per tween. + + If TRUE forces startup even if it had already been executed + + + + Manages on first start behaviour. + + + + + Manages on play behaviour + + + + + Fills the given list with all the plugins inside this tween. + Used by HOTween.GetPlugins. + + + + + Returns the correct id of the given waypoint, converted to path id. + + Vector3 path plugin to use + Waypoint to convert + If TRUE indicates that the given waypoint is the starting one, + otherwise it's the ending one + + + + + Indicates whether this is a FROM or a TO tween. + + + + + Ease type of this tweener + (consider that the plugins you have set might have different ease types). + Setting it will change the ease of all the plugins used by this tweener. + + + + + Ease type of this tweener + (consider that the plugins you have set might have different ease types). + Setting it will change the ease of all the plugins used by this tweener. + + + + + Eventual overshoot to use with Back easeTypes. + + + + + Eventual period to use with Elastic easeTypes. + + + + + Target of this tween. + + + + + true if this tween is animated via integers values only. + + + + + true if this tween is animated by speed instead than by duration. + + + + + The delay that was set for this tween. + + + + + The currently elapsed delay time. + + + + + Default plugin for the tweening of Rect objects. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Type of path (used with ) + + + + + Straight path + + + + + Curved (Catmull-Rom) path + + + + + Main tween manager. + Controls all tween types ( and ), + and is used to directly create Tweeners (to create Sequences, directly create a new instead). + Author: LXFDaniele Giardini (http://www.holoville.com) + + + + + HOTween author - me! :P + + + + + HOTween version. + + + + + Default that will be used by any new Tweener/Sequence that doesn't implement a specific ease + (default = EaseType.easeOutQuad) + + + + + Default time scale that will be used by any new Tweener/Sequence that doesn't implement a specific timeScale + (default = 1). + + + + + Default that will be used by any new Tweener/Sequence that doesn't implement a specific ease + (default = EaseType.easeOutQuad). + + + + + Default overshoot to use with Back easeTypes. + + + + + Default period to use with Elastic easeTypes. + + + + + Default that will be used by any Tweener/Sequence that doesn't implement a specific loopType + (default = LoopType.Restart). + + + + + If true, shows the eventual paths in use by + while playing inside Unity's Editor (and if the Editor's Gizmos button is on). + + + + + Level of message output in case an error is encountered. + Warnings are logged when HOTween encounters an error, and automatically resolves it without throwing any exception + (like if you try to tween an unexisting property, in which case the tween simply won't be generated, + and an eventual warning will appear in the output window). + + + + + true if the current player is iOS (iPhone). + Used so simple Reflection instead than unsupported MemberAccessorCacher will be applyed + (iOS doesn't support Reflection.Emit). + + + + + true if the current player is running in the Editor. + + + + + Filled by tweens that are completed, so that their onCompleteDispatch method can be called AFTER HOTween has eventually removed them + (otherwise a Kill + To on the same target won't work). + This field is emptied as soon as all onCompletes are called. + + + + + Reference to overwrite manager (if in use). + + + + + Initializes and sets it as non-permanent + (meaning HOTween instance will be destroyed when all tweens are killed, + and re-created when needed). + Call this method once when your application starts up, + to avoid auto-initialization when the first tween is started or created, + and to set options. + + + + + Initializes . + Call this method once when your application starts up, + to avoid auto-initialization when the first tween is started or created, + and to set options. + + + If set to true, doesn't destroy HOTween manager when no tween is present, + otherwise the manager is destroyed when all tweens have been killed, + and re-created when needed. + + + + + Initializes . + Call this method once when your application starts up, + to avoid auto-initialization when the first tween is started or created, + and to set options. + + + If set to true, doesn't destroy HOTween manager when no tween is present, + otherwise the manager is destroyed when all tweens have been killed, + and re-created when needed. + + + If true, renames HOTween's instance to show + the current number of running tweens (only while in the Editor). + + + If true, allows HOTween's instance to enable or disable + the OverwriteManager to improve performance if it is never needed. + + + + + Called internally each time a new is created. + Adds the given Sequence to the tween list. + + + The to add. + + + + + Creates a new absolute tween with default values, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + + The duration in seconds of the tween. + + + The name of the property or field to tween. + + + The end value the property should reach with the tween. + + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new tween with default values, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + + The duration in seconds of the tween. + + + The name of the property or field to tween. + + + The end value the property should reach with the tween. + + + If true treats the end value as relative (tween BY instead than tween TO), otherwise as absolute. + + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new tween with default values, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + + The duration in seconds of the tween. + + + The name of the property or field to tween. + + + The end value the property should reach with the tween. + + + If true treats the end value as relative (tween BY instead than tween TO), otherwise as absolute. + + + The ease to use. + + + The eventual delay to apply. + + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new tween and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + + The duration in seconds of the tween. + + + A representing the tween parameters. + You can pass an existing one, or create a new one inline via method chaining, + like new TweenParms().Prop("x",10).Loops(2).OnComplete(myFunction) + + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new absolute FROM tween with default values, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + + The duration in seconds of the tween. + + + The name of the property or field to tween. + + + The end value the property should reach with the tween. + + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new FROM tween with default values, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + + The duration in seconds of the tween. + + + The name of the property or field to tween. + + + The end value the property should reach with the tween. + + + If true treats the end value as relative (tween BY instead than tween TO), otherwise as absolute. + + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new FROM tween with default values, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + + The duration in seconds of the tween. + + + The name of the property or field to tween. + + + The end value the property should reach with the tween. + + + If true treats the end value as relative (tween BY instead than tween TO), otherwise as absolute. + + + The ease to use. + + + The eventual delay to apply. + + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new FROM tween and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + + The duration in seconds of the tween. + + + A representing the tween parameters. + You can pass an existing one, or create a new one inline via method chaining, + like new TweenParms().Prop("x",10).Loops(2).OnComplete(myFunction) + + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new absolute PUNCH tween, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + The duration in seconds of the tween. + The name of the property or field to tween. + The end value the property should reach with the tween. + Default: 0.5f - amplitude of the punch effect + Default: 0.1f - oscillation period of punch effect + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new PUNCH tween, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + The duration in seconds of the tween. + The name of the property or field to tween. + The end value the property should reach with the tween. + + If true treats the end value as relative (tween BY instead than tween TO), otherwise as absolute. + + Default: 0.5f - amplitude of the punch effect + Default: 0.1f - oscillation period of punch effect + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new PUNCH tween and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + Any ease type passed won't be considered, since punch uses its own one. + + + The tweening target (must be the object containing the properties or fields to tween). + + The duration in seconds of the tween. + + A representing the tween parameters. + You can pass an existing one, or create a new one inline via method chaining, + like new TweenParms().Prop("x",10).Loops(2).OnComplete(myFunction) + + Default: 0.5f - amplitude of the punch effect + Default: 0.1f - oscillation period of punch effect + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new absolute SHAKE tween, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + The duration in seconds of the tween. + The name of the property or field to tween. + The amount of shaking to apply. + Default: 0.1f - amplitude of the shake effect + Default: 0.12f - oscillation period of shake effect + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new SHAKE tween, and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + + + The tweening target (must be the object containing the properties or fields to tween). + + The duration in seconds of the tween. + The name of the property or field to tween. + The amount of shaking to apply. + + If true treats the end value as relative (tween BY instead than tween TO), otherwise as absolute. + + Default: 0.1f - amplitude of the shake effect + Default: 0.12f - oscillation period of shake effect + + The newly created , + or null if the parameters were invalid. + + + + + Creates a new SHAKE tween and returns the representing it, + or null if the tween was invalid (no valid property to tween was given). + Any ease type passed won't be considered, since shake uses its own one. + + + The tweening target (must be the object containing the properties or fields to tween). + + The duration in seconds of the tween. + + A representing the tween parameters. + You can pass an existing one, or create a new one inline via method chaining, + like new TweenParms().Prop("x",10).Loops(2).OnComplete(myFunction) + + Default: 0.1f - amplitude of the shake effect + Default: 0.12f - oscillation period of shake effect + + The newly created , + or null if the parameters were invalid. + + + + + Updates normal tweens. + + + + + Updates lateUpdate tweens. + + + + + Updates fixedUpdate tweens. + + + + + Updates timeScaleIndependent tweens. + + + + + Enables the overwrite manager (disabled by default). + + If TRUE, the overwriteManager will log a warning each time a tween is overwritten + + + + Disables the overwrite manager (disabled by default). + + + + + Pauses all the tweens for the given target, and returns the total number of paused Tweeners. + + + The target whose tweens to pause. + + + The total number of paused Tweeners. + + + + + Pauses all the Tweeners/Sequences with the given ID, and returns the total number of paused Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to pause. + + + The total number of paused Tweeners/Sequences. + + + + + Pauses all the Tweeners/Sequences with the given intId, and returns the total number of paused Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to pause. + + + The total number of paused Tweeners/Sequences. + + + + + Pauses the given Tweener, and returns the total number of paused ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to pause. + + + The total number of paused Tweener (1 if the Tweener existed, otherwise 0). + + + + + Pauses the given Sequence, and returns the total number of paused ones (1 if the Sequence existed, otherwise 0). + + + The Sequence to pause. + + + The total number of paused Sequence (1 if the sequence existed, otherwise 0). + + + + + Pauses all Tweeners/Sequences, and returns the total number of paused Tweeners/Sequences. + + + The total number of paused Tweeners/Sequences. + + + + + Resumes all the tweens (delays included) for the given target, and returns the total number of resumed Tweeners. + + + The target whose tweens to resume. + + + The total number of resumed Tweeners. + + + + + Resumes all the tweens for the given target, and returns the total number of resumed Tweeners. + + + The target whose tweens to resume. + + + If true skips any initial delay. + + + The total number of resumed Tweeners. + + + + + Resumes all the Tweeners (delays included) and Sequences with the given ID, and returns the total number of resumed Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to resume. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the Tweeners/Sequences with the given ID, and returns the total number of resumed Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to resume. + + + If true skips any initial tween delay. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the Tweeners (delays included) and Sequences with the given intId, and returns the total number of resumed Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to resume. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the Tweeners/Sequences with the given intId, and returns the total number of resumed Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to resume. + + + If true skips any initial tween delay. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes the given Tweener (delays included), and returns the total number of resumed ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to resume. + + + The total number of resumed Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Resumes the given Tweener, and returns the total number of resumed ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to resume. + + + If true skips any initial delay. + + + The total number of resumed Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Resumes the given Sequence, and returns the total number of resumed ones (1 if the Sequence existed, otherwise 0). + + + The Sequence to resume. + + + The total number of resumed Sequences (1 if the Sequence existed, otherwise 0). + + + + + Resumes all Tweeners (delays included) and Sequences, and returns the total number of resumed Tweeners/Sequences. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all Tweeners/Sequences, and returns the total number of resumed Tweeners/Sequences. + + + If true skips any initial tween delay. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the tweens (delays included) for the given target, + sets the tweens so that they move forward and not backwards, + and returns the total number of resumed Tweeners. + + + The target whose tweens to resume. + + + The total number of resumed Tweeners. + + + + + Resumes all the tweens for the given target, + sets the tweens so that they move forward and not backwards, + and returns the total number of resumed Tweeners. + + + The target whose tweens to resume. + + + If true skips any initial delay. + + + The total number of resumed Tweeners. + + + + + Resumes all the Tweeners (delays included) and Sequences with the given ID, + sets the tweens so that they move forward and not backwards, + and returns the total number of resumed Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to resume. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the Tweeners/Sequences with the given ID, + sets the tweens so that they move forward and not backwards, + and returns the total number of resumed Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to resume. + + + If true skips any initial tween delay. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the Tweeners (delays included) and Sequences with the given intId, + sets the tweens so that they move forward and not backwards, + and returns the total number of resumed Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to resume. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the Tweeners/Sequences with the given intId, + sets the tweens so that they move forward and not backwards, + and returns the total number of resumed Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to resume. + + + If true skips any initial tween delay. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes the given Tweener (delays included), + sets it so that it moves forward and not backwards, + and returns the total number of resumed ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to resume. + + + The total number of resumed Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Resumes the given Tweener, + sets it so that it moves forward and not backwards, + and returns the total number of resumed ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to resume. + + + If true skips any initial delay. + + + The total number of resumed Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Resumes the given Sequence, + sets it so that it moves forward and not backwards, + and returns the total number of resumed ones (1 if the Sequence existed, otherwise 0). + + + The Sequence to resume. + + + The total number of resumed Sequences (1 if the Sequence existed, otherwise 0). + + + + + Resumes all Tweeners (delays included) and Sequences, + sets the tweens so that they move forward and not backwards, + and returns the total number of resumed Tweeners/Sequences. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all Tweeners/Sequences, + sets the tweens so that they move forward and not backwards, + and returns the total number of resumed Tweeners/Sequences. + + + If true skips any initial tween delay. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the tweens for the given target, + sets the tweens so that they move backwards instead than forward, + and returns the total number of resumed Tweeners. + + + The target whose tweens to resume. + + + The total number of resumed Tweeners. + + + + + Resumes all the Tweeners/Sequences with the given ID, + sets the tweens so that they move backwards instead than forward, + and returns the total number of resumed Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to resume. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes all the Tweeners/Sequences with the given intId, + sets the tweens so that they move backwards instead than forward, + and returns the total number of resumed Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to resume. + + + The total number of resumed Tweeners/Sequences. + + + + + Resumes the given Tweener, + sets it so that it moves backwards instead than forward, + and returns the total number of resumed ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to resume. + + + The total number of resumed Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Resumes the given Sequence, + sets it so that it moves backwards instead than forward, + and returns the total number of resumed ones (1 if the Sequence existed, otherwise 0). + + + The Sequence to resume. + + + The total number of resumed Sequences (1 if the Sequence existed, otherwise 0). + + + + + Resumes all Tweeners/Sequences, + sets the tweens so that they move backwards instead than forward, + and returns the total number of resumed Tweeners/Sequences. + + + The total number of resumed Tweeners/Sequences. + + + + + Rewinds all the tweens (delays included) for the given target, and returns the total number of rewinded Tweeners. + + + The target whose tweens to rewind. + + + The total number of rewinded Tweeners. + + + + + Rewinds all the tweens for the given target, and returns the total number of rewinded Tweeners. + + + The target whose tweens to rewind. + + + If true skips any initial delay. + + + The total number of rewinded Tweeners. + + + + + Rewinds all the Tweeners (delays included) and Sequences with the given ID, and returns the total number of rewinded Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to rewind. + + + The total number of rewinded Tweeners/Sequences. + + + + + Rewinds all the Tweeners/Sequences with the given ID, and returns the total number of rewinded Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to rewind. + + + If true skips any initial tween delay. + + + The total number of rewinded Tweeners/Sequences. + + + + + Rewinds all the Tweeners (delays included) and Sequences with the given intId, and returns the total number of rewinded Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to rewind. + + + The total number of rewinded Tweeners/Sequences. + + + + + Rewinds all the Tweeners/Sequences with the given intId, and returns the total number of rewinded Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to rewind. + + + If true skips any initial tween delay. + + + The total number of rewinded Tweeners/Sequences. + + + + + Rewinds the given Tweener (delays included), and returns the total number of rewinded ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to rewind. + + + The total number of rewinded Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Rewinds the given Tweener, and returns the total number of rewinded ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to rewind. + + + If true skips any initial delay. + + + The total number of rewinded Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Rewinds the given Sequence, and returns the total number of rewinded ones (1 if the Sequence existed, otherwise 0). + + + The Sequence to rewind. + + + The total number of rewinded Sequences (1 if the Sequence existed, otherwise 0). + + + + + Rewinds all Tweeners (delay included) and Sequences, and returns the total number of rewinded Tweeners/Sequences. + + + The total number of rewinded Tweeners/Sequences. + + + + + Rewinds all Tweeners/Sequences, and returns the total number of rewinded Tweeners/Sequences. + + + If true skips any initial tween delay. + + + The total number of rewinded Tweeners/Sequences. + + + + + Restarts all the tweens (delays included) for the given target, and returns the total number of restarted Tweeners. + + + The target whose tweens to restart. + + + The total number of restarted Tweeners. + + + + + Restarts all the tweens for the given target, and returns the total number of restarted Tweeners. + + + The target whose tweens to restart. + + + If true skips any initial delay. + + + The total number of restarted Tweeners. + + + + + Restarts all the Tweeners (delays included) and Sequences with the given ID, and returns the total number of restarted Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to restart. + + + The total number of restarted Tweeners/Sequences. + + + + + Restarts all the Tweeners/Sequences with the given ID, and returns the total number of restarted Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to restart. + + + If true skips any initial tween delay. + + + The total number of restarted Tweeners/Sequences. + + + + + Restarts all the Tweeners (delays included) and Sequences with the given intId, and returns the total number of restarted Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to restart. + + + The total number of restarted Tweeners/Sequences. + + + + + Restarts all the Tweeners/Sequences with the given intId, and returns the total number of restarted Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to restart. + + + If true skips any initial tween delay. + + + The total number of restarted Tweeners/Sequences. + + + + + Restarts the given Tweener (delays included), and returns the total number of restarted ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to restart. + + + The total number of restarted Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Restarts the given Tweener, and returns the total number of restarted ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to restart. + + + If true skips any initial delay. + + + The total number of restarted Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Restarts the given Sequence, and returns the total number of restarted ones (1 if the Sequence existed, otherwise 0). + + + The Sequence to restart. + + + The total number of restarted Sequences (1 if the Sequence existed, otherwise 0). + + + + + Restarts all Tweeners/Sequences (delay included) and Sequences, and returns the total number of restarted Tweeners/Sequences. + + + The total number of restarted Tweeners/Sequences. + + + + + Restarts all Tweeners/Sequences and returns the total number of restarted Tweeners/Sequences. + + + If true skips any initial tween delay. + + + The total number of restarted Tweeners/Sequences. + + + + + Restarts all tweens from position 0, but recalculating them by taking their current targets values as start values, + and the currently changed value to determine the end values. + + + The target whose tweens to restart. + + + The total number of restarted Tweeners. + + + + + Restarts all the Tweeners from position 0, but recalculating them by taking their current targets values as start values, + and the currently changed value to determine the end values. + + + The ID of the Tweeners/Sequences to restart. + + + The total number of restarted Tweeners/Sequences. + + + + + Restarts all the Tweeners from position 0, but recalculating them by taking their current targets values as start values, + and the currently changed value to determine the end values. + + + The intId of the Tweeners/Sequences to restart. + + + The total number of restarted Tweeners/Sequences. + + + + + Restarts the given Tweener from position 0, but recalculating them by taking their current targets values as start values, + and the currently changed value to determine the end values. + + + The Tweener to restart. + + + The total number of restarted Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Restarts all Tweeners/Sequences from position 0, but recalculating them by taking their current targets values as start values, + and the currently changed value to determine the end values. + + + The total number of restarted Tweeners/Sequences. + + + + + Reverses all the tweens for the given target, + animating them from their current value back to the starting one, + and returns the total number of reversed Tweeners. + + + The target whose tweens to reverse. + + + If TRUE, the tween will also start playing in case it was paused, + otherwise it will maintain its current play/pause state (default). + + + The total number of reversed Tweeners. + + + + + Reverses all the Tweeners/Sequences with the given ID, + animating them from their current value back to the starting one, + and returns the total number of reversed Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to reverse. + + + If TRUE, the tween will also start playing in case it was paused, + otherwise it will maintain its current play/pause state (default). + + + The total number of reversed Tweeners/Sequences. + + + + + Reverses all the Tweeners/Sequences with the given intId, + animating them from their current value back to the starting one, + and returns the total number of reversed Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to reverse. + + + If TRUE, the tween will also start playing in case it was paused, + otherwise it will maintain its current play/pause state (default). + + + The total number of reversed Tweeners/Sequences. + + + + + Reverses the given Tweener, + animating it from its current value back to the starting one, + and returns the total number of reversed Tweeners (1 if the Tweener existed, otherwise 0). + + + The Tweener to reverse. + + + If TRUE, the tween will also start playing in case it was paused, + otherwise it will maintain its current play/pause state (default). + + + The total number of reversed Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Reverses the given Sequence, and returns the total number of reversed ones (1 if the Sequence existed, otherwise 0). + + + The Sequence to reverse. + + + If TRUE, the tween will also start playing in case it was paused, + otherwise it will maintain its current play/pause state (default). + + + The total number of reversed Sequences (1 if the Sequence existed, otherwise 0). + + + + + Reverses all Tweeners/Sequences, + animating them from their current value back to the starting one, + and returns the total number of reversed Tweeners/Sequences. + + + If TRUE, the tween will also start playing in case it was paused, + otherwise it will maintain its current play/pause state (default). + + + The total number of reversed Tweeners/Sequences. + + + + + Completes all the tweens for the given target, and returns the total number of completed Tweeners. + Where a loop was involved and not infinite, the relative tween completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + The target whose tweens to complete. + + + The total number of completed Tweeners. + + + + + Completes all the Tweeners/Sequences with the given ID, and returns the total number of completed Tweeners/Sequences. + Where a loop was involved and not infinite, the relative Tweener/Sequence completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + The ID of the Tweeners/Sequences to complete. + + + The total number of completed Tweeners/Sequences. + + + + + Completes all the Tweeners/Sequences with the given intId, and returns the total number of completed Tweeners/Sequences. + Where a loop was involved and not infinite, the relative Tweener/Sequence completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + The intId of the Tweeners/Sequences to complete. + + + The total number of completed Tweeners/Sequences. + + + + + Completes the given Tweener, and returns the total number of completed ones (1 if the Tweener existed, otherwise 0). + Where a loop was involved and not infinite, the relative Tweener completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + The Tweener to complete. + + + The total number of completed Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Completes the given Sequence, and returns the total number of completed ones (1 if the Sequence existed, otherwise 0). + Where a loop was involved and not infinite, the relative Sequence completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + The Sequence to complete. + + + The total number of completed Sequences (1 if the Sequence existed, otherwise 0). + + + + + Completes all Tweeners/Sequences, and returns the total number of completed Tweeners/Sequences. + Where a loop was involved and not infinite, the relative Tweener/Sequence completes at the position where it would actually be after the set number of loops. + If there were infinite loops, this method will have no effect. + + + The total number of completed Tweeners/Sequences. + + + + + Kills all the tweens for the given target (unless they're were created inside a ), + and returns the total number of killed Tweeners. + + + The target whose Tweeners to kill. + + + The total number of killed Tweeners. + + + + + Kills all the Tweeners/Sequences with the given ID, and returns the total number of killed Tweeners/Sequences. + + + The ID of the Tweeners/Sequences to kill. + + + The total number of killed Tweeners/Sequences. + + + + + Kills all the Tweeners/Sequences with the given intId, and returns the total number of killed Tweeners/Sequences. + + + The intId of the Tweeners/Sequences to kill. + + + The total number of killed Tweeners/Sequences. + + + + + Kills the given Tweener, and returns the total number of killed ones (1 if the Tweener existed, otherwise 0). + + + The Tweener to kill. + + + The total number of killed Tweeners (1 if the Tweener existed, otherwise 0). + + + + + Kills the given Sequence, and returns the total number of killed ones (1 if the Sequence existed, otherwise 0). + + + The Sequence to kill. + + + The total number of killed Sequences (1 if the Sequence existed, otherwise 0). + + + + + Kills all Tweeners/Sequences, and returns the total number of killed Tweeners/Sequences. + + + The total number of killed Tweeners/Sequences. + + + + + Used by Sequences to remove added tweens from main tweens list. + + + + + + Returns all existing Tweeners (excluding nested ones) and Sequences, paused or not. + + + + + Returns all existing Tweeners (excluding nested ones) and Sequences that are currently playing. + + + + + Returns all existing Tweeners (excluding nested ones) and Sequences that are currently paused. + + + + + Returns a list of the eventual existing tweens with the given Id, + (empty if no Tweener/Sequence was found). + + Id to look for + If TRUE also searches inside nested tweens + + + + + Returns a list of the eventual existing tweens with the given intId, + (empty if no Tweener/Sequence was found). + + IntId to look for + If TRUE also searches inside nested tweens + + + + + Returns a list with all the existing objects whose target is the given one, + or an empty list if none was found. + + Target to look for + If TRUE also searches inside nested Tweeners + + + + + Returns true if the given target is currently involved in any running Tweener or Sequence (taking into account also nested tweens). + Returns false both if the given target is not inside a Tweener, than if the relative Tweener is paused. + To simply check if the target is attached to a Tweener or Sequence use instead. + + + The target to check. + + + A value of true if the given target is currently involved in any running Tweener or Sequence (taking into account also nested tweens). + + + + + Returns true if the given id is involved in any running Tweener or Sequence (taking into account also nested tweens). + + + The target to check. + + + + + Returns true if the given id is involved in any running Tweener or Sequence (taking into account also nested tweens). + + + The target to check. + + + + + Returns true if the given target is linked to any Tweener or Sequence (running or not, taking into account also nested tweens). + + + The target to check. + + + A value of true if the given target is linked to any Tweener or Sequence (running or not, taking into account also nested tweens). + + + + + Returns a list of the current tweens (paused and delayed included), + or null if there are no tweens. + + + + + + Used by callbacks that are wired to sendMessage. + + + + + Filter filters for: + - ID if + - Tweener if + - Sequence if + - Tweener target if (doesn't look inside sequence tweens) + - Everything if null + + + + + Returns all the currently existing plugins involved in any tween, even if nested or paused, + or null if there are none. + + + + + TRUE while inside the update loop + + + + + Total number of tweeners/sequences (paused and delayed ones are included). + Tweeners and sequences contained into other sequences don't count: + for example, if there's only one sequence that contains 2 tweeners, totTweens will be 1. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a quadratic (t^2) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a quadratic (t^2) easing out: decelerating to zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a quadratic (t^2) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a simple linear tweening, with no easing. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Base class for all HOTParms. + + + + + ID. + + + + + Int ID. + + + + + Auto kill on complete. + + + + + Update type. + + + + + Time scale. + + + + + Loops + + + + + Loop type. + + + + + Paused. + + + + + On start. + + + + + On start with parms. + + + + + On start parameters. + + + + + On update. + + + + + On update with parms. + + + + + On update parameters. + + + + + On plugin results. + + + + + On plugin results with parms. + + + + + On plugin results parameters. + + + + + On pause. + + + + + On pause with parms. + + + + + On pause parameters. + + + + + On play. + + + + + On play with parms. + + + + + On play parameters. + + + + + On rewinded. + + + + + On rewinded with parms. + + + + + On rewinded parameters. + + + + + On step complete. + + + + + On step complete with parms. + + + + + On step complete parameters. + + + + + On complete. + + + + + On complete with parms. + + + + + On complete parameters. + + + + + True if there are behaviours to manage + + + + + True if there are gameObject to manage + + + + + Behaviours to activate + + + + + Behaviours to deactivate + + + + + GameObjects to activate + + + + + GameObejcts to deactivate + + + + + Initializes the given owner with the stored parameters. + + + The to initialize. + + + + + Only used with ApplyCallback method. + + + + + Called when the tween is starting + + + + + Called each time the tween is updated + + + + + Called each time a single loop is completed + + + + + Called when the whole tween (loops included) is complete + + + + + Called when the tween is paused + + + + + Called when the tween is played + + + + + Called when the tween is rewinded + + + + + Works only with Tweeners, and not with Sequences. + Called when a plugin of the Tweens is overwritten by the OverwriteManager. + + + + + Cache manager for James Nies' MemberAccessor classes + + + + + Returns the cached memberAccessor if it alread exists, + or calls MemberAccessor.Make and caches and returns the newly created MemberAccessor. + + + + + Clears the cache. + + + + + The PropertyAccessor class provides fast dynamic access + to a property of a specified target class. + + + + + Creates a new property accessor. + + + + + The Type of the Property being accessed. + + + + + Whether or not the Property supports read access. + + + + + Whether or not the Property supports write access. + + + + + Enumeration of axis. + + + + + No axis. + + + + + X axis. + + + + + Y axis. + + + + + Z axis. + + + + + W axis. + + + + + Plugin for the tweening of Vector3 objects along a Vector3 path. + + + + + Creates a new instance of this plugin using the main ease type and an absolute path. + + + The path to tween through. + + Type of path + + + + Creates a new instance of this plugin using an absolute path. + + + The path to tween through. + + + The to use. + + Type of path + + + + Creates a new instance of this plugin using the main ease type. + + + The path to tween through. + + + If true, the path is considered relative to the starting value of the property, instead than absolute. + Not compatible with HOTween.From. + + Type of path + + + + Creates a new instance of this plugin. + + + The path to tween through. + + + The to use. + + + If true, the path is considered relative to the starting value of the property, instead than absolute. + Not compatible with HOTween.From. + + Type of path + + + + Creates a new instance of this plugin. + + + The path to tween through. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + Type of path + + + + Init override. + Used to check that isRelative is FALSE, + and otherwise use the given parameters to send a decent warning message. + + + + + Parameter > Smoothly closes the path, so that it can be used for cycling loops. + + + A + + + + + Parameter > Choose whether to smoothly close the path, so that it can be used for cycling loops. + + + Set to true to close the path. + + + + + Parameter > If the tween target is a , orients the tween target to the path. + + + A + + + + + Parameter > Choose whether to orient the tween target to the path (only if it's a ). + + + Set to true to orient the tween target to the path. + + + + + Parameter > If the tween target is a , orients the tween target to the path, + using the given lookAhead percentage. + + + The look ahead percentage (0 to 1). + + + + + Parameter > If the tween target is a , orients the tween target to the path, + locking its rotation on the given axis. + + + Sets one or more axis to lock while rotating. + To lock more than one axis, use the bitwise OR operator (ex: Axis.X | Axis.Y). + + + + + Parameter > If the tween target is a , orients the tween target to the path, + using the given lookAhead percentage and locking its rotation on the given axis. + + The look ahead percentage (0 to 1) + + Sets one or more axis to lock while rotating. + To lock more than one axis, use the bitwise OR operator (ex: Axis.X | Axis.Y). + + + + + Parameter > Choose whether to orient the tween target to the path (only if it's a ), + and which lookAhead percentage ad lockRotation to use. + + + Set to true to orient the tween target to the path. + + + The look ahead percentage (0 to 1). + + + Sets one or more axis to lock while rotating. + To lock more than one axis, use the bitwise OR operator (ex: Axis.X | Axis.Y). + + + + + Parameter > If the tween target is a , sets the tween so that the target will always look at the given transform. + + + The to look at. + + + + + Parameter > If the tween target is a , sets the tween so that the target will always look at the given position. + + + The to look at. + + + + + Parameter > locks the given position axis. + + Sets one or more axis to lock. + To lock more than one axis, use the bitwise OR operator (ex: Axis.X | Axis.Y) + + + + + Indicates that the path works must be calculated in 2D + + If TRUE the target will be considered as moving from a side-scrolling perspective, + if FALSE (default) the target will be considered as moving from a top-down perspective + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Adds the correct starting and ending point so the path can be reached from the property's actual position. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Returns the point at the given percentage (0 to 1), + considering the path at constant speed. + Used by DoUpdate and by Tweener.GetPointOnPath. + + + The percentage (0 to 1) at which to get the point. + + + + + Returns the point at the given percentage (0 to 1), + considering the path at constant speed. + Used by DoUpdate and by Tweener.GetPointOnPath. + + + The percentage (0 to 1) at which to get the point. + + + IF true updates also value + (necessary if this method is called for an update). + + + IF not NULL uses the given path instead than the default one. + + + Index of waypoint we're moving to (or where we are). Only used for Linear paths. + + + + + Returns the percentage of the path length occupied by the given path waypoints interval. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Manager used for automatic control of eventual overwriting of tweens. + It is disabled by default, you need to call to enable it. + + + + + List of currently running Tweeners + (meaning all Tweeners whose OnStart has been called, paused or not). + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a quintic (t^5) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a quintic (t^5) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a quintic (t^5) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Default plugin for the tweening of Color32 objects. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Used internally to generate warnings that are managed without throwing exceptions. + + + + + Used to manage movement on a Cardinal spline (of Catmull-Rom type). + Contains code from Andeeee's CRSpline (http://forum.unity3d.com/threads/32954-Waypoints-and-constant-variable-speed-problems). + + + + + Creates a new based on the given array of points. + + Type of path + + The array used to create the path. + + + + + Gets the point on the path at the given percentage (0 to 1). + + + The percentage (0 to 1) at which to get the point. + + + + + Gets the point on the path at the given percentage (0 to 1). + + + The percentage (0 to 1) at which to get the point. + + + Index of waypoint we're moving to (or where we are). Only used for Linear paths. + + + + + Gets the velocity at the given time position. + OBSOLETE since path now uses constant velocity. + + + + + Draws the full path. + + + + + Draws the full path, and if t is not -1 also draws the velocity at t. + + + The point where to calculate velocity and eventual additional trigonometry. + + + If true also draws the normal, tangent, and binormal of t. + + + + + Returns the point at the given time percentage (0 to 1), + considering the path at constant speed. + + The time percentage (0 to 1) at which to get the point + + + + Returns the point at the given time percentage (0 to 1), + considering the path at constant speed. + + The time percentage (0 to 1) at which to get the point + Outputs the calculated path percentage value + + Index of waypoint we're moving to (or where we are). Only used for Linear paths. + + + + + Gets the constant path percentage for the given time percentage + that can be used with GetConstPoint. + + The time percentage (0 to 1) to use + + + + + Method chaining parameters for a . + + + + + Initializes the given with the stored parameters. + + + The to initialize. + + + The target. + + + + + Sets this tween so that it works with pixel perfect values. + Only works with , , , + , , + plugins. + + + + + + Sets this tween to work by speed instead than time. + When a tween is based on speed instead than time, + duration is considered as the amount that the property will change every second, + and ease is automatically set to Linear. + In case of Vectors, the amount represents the vector length x second; + in case of Quaternions, the amount represents the full rotation (360°) speed x second; + in case of strings, the amount represents the amount of changed letters x second. + + + + + Sets whether to tween by speed or not. + When a tween is based on speed instead than time, + duration is considered as the amount that the property will change every second, + and ease is automatically set to Linear. + In case of Vectors, the amount represents the vector length x second; + in case of strings, the amount represents the amount of changed letters x second. + + + If true this tween will work by speed instead than by time. + + + + + Sets the ease type to use (default = EaseType.easeOutQuad). + If you set this tween to use speed instead than time, + this parameter becomes useless, because it will be managed internally. + + + The to use. + + + + + Sets the ease type to use (default = EaseType.easeOutQuad). + If you set this tween to use speed instead than time, + this parameter becomes useless, because it will be managed internally. + + + The to use. + + + Eventual overshoot to use with Back easeType (default is 1.70158). + + + + + Sets the ease type to use (default = EaseType.easeOutQuad). + If you set this tween to use speed instead than time, + this parameter becomes useless, because it will be managed internally. + + + The to use. + + + Eventual amplitude to use with Elastic easeType (default is 0). + + + Eventual period to use with Elastic easeType (default is 0). + + + + + Sets the ease to use the given AnimationCurve. + If you set this tween to use speed instead than time, + this parameter becomes useless, because it will be managed internally. + + + The to use. + + + + + Sets the seconds of delay before the tween should start (default = 0). + + + The seconds of delay. + + + + + Sets the Tweener in a paused state. + + + + + Choose whether to set the Tweener in a paused state. + + + + + Sets a property or field to tween, + directly assigning the given TweenPlugin to it. + Behaves as Prop(), but removes any other property tween previously set in this + (useful if you want to reuse the same parameters with a new set of property tweens). + + + The name of the property. + + + The to use. + + + + + Sets a property or field to tween. + Behaves as Prop(), but removes any other property tween previously set in this + (useful if you want to reuse the same parameters with a new set of property tweens). + + + The name of the property. + + + The absolute end value the object should reach with the tween. + + + + + Sets a property or field to tween. + Behaves as Prop(), but removes any other property tween previously set in this + (useful if you want to reuse the same parameters with a new set of property tweens). + + + The name of the property. + + + The end value the object should reach with the tween. + + + If true treats the end value as relative, otherwise as absolute. + + + + + Sets a property or field to tween, + directly assigning the given TweenPlugin to it. + Behaves as NewProp(), but without removing the other property tweens that were set in this . + + + The name of the property. + + + The to use. + + + + + Sets a property or field to tween. + Behaves as NewProp(), but without removing the other property tweens that were set in this . + + + The name of the property. + + + The absolute end value the object should reach with the tween. + + + + + Sets a property or field to tween. + Behaves as NewProp(), but without removing the other property tweens that were set in this . + + + The name of the property. + + + The end value the object should reach with the tween. + + + If true treats the end value as relative, otherwise as absolute. + + + + + Sets the ID of this Tweener (default = ""). + The same ID can be applied to multiple Tweeners, thus allowing for group operations. + You can also use IntId instead of Id for faster operations. + + + The ID for this Tweener. + + + + + Sets the int ID of this Tweener (default = 0). + The same intId can be applied to multiple Tweeners, thus allowing for group operations. + The main difference from Id is that while Id is more legible, IntId allows for faster operations. + + + The int ID for this Tweener. + + + + + Sets auto-kill behaviour for when the Tweener reaches its end (default = false). + + + If true the Tweener is killed and removed from HOTween as soon as it's completed. + If false doesn't remove this Tweener from HOTween when it is completed, + and you will need to call an HOTween.Kill to remove this Tweener. + + + + + Sets the type of update to use for this Tweener (default = .Update). + + + The type of update to use. + + + + + Sets the time scale that will be used by this Tweener. + + + The time scale to use. + + + + + Sets the number of times the Tweener will run (default = 1, meaning only one go and no other loops). + + + Number of loops (set it to -1 or to apply infinite loops). + + + + + Sets the number of times the Tweener will run, + and the type of loop behaviour to apply + (default = 1, LoopType.Restart). + + + Number of loops (set it to -1 or to apply infinite loops). + + + The behaviour to use. + + + + + Function to call when the Tweener is started for the very first time. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when the Tweener is started for the very first time. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call each time the Tweener is updated. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call each time the Tweener is updated. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call each time a plugin is updated. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call when the Tweener switches from a playing state to a paused state. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when the Tweener switches from a playing state to a paused state. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call when the Tweener switches from a paused state to a playing state. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when the Tweener switches from a paused state to a playing state. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call each time the Tweener is rewinded from a non-rewinded state + (either because of a direct call to Rewind, + or because the tween's virtual playehead reached the start due to a playing backwards behaviour). + + + The function to call, who must return void and accept no parameters. + + + + + Function to call each time the Tweener is rewinded from a non-rewinded state + (either because of a direct call to Rewind, + or because the tween's virtual playehead reached the start due to a playing backwards behaviour). + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call each time a single loop of the Tweener is completed. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call each time a single loop of the Tweener is completed. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Uses sendMessage to call the method named p_methodName + on every MonoBehaviour in the p_sendMessageTarget GameObject. + + GameObject to target for sendMessage + Name of the method to call + Eventual additional parameter + SendMessageOptions + + + + Function to call when the full Tweener, loops included, is completed. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when the full Tweener, loops included, is completed. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Uses sendMessage to call the method named p_methodName + on every MonoBehaviour in the p_sendMessageTarget GameObject. + + GameObject to target for sendMessage + Name of the method to call + Eventual additional parameter + SendMessageOptions + + + + Function to call when one of the plugins used in the tween gets overwritten + (available only if OverwriteManager is active). + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when one of the plugins used in the tween gets overwritten + (available only if OverwriteManager is active). + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Keeps the given component enabled while the tween is playing + + + + + Keeps the given gameObject activated while the tween is playing + + + + + Keeps the given components enabled while the tween is playing + + + + + Keeps the given GameObject activated while the tween is playing + + + + + Keeps the given component disabled while the tween is playing + + + + + Keeps the given GameObject disabled while the tween is playing + + + + + Keeps the given components disabled while the tween is playing + + + + + Keeps the given GameObject disabled while the tween is playing + + + + + Used by HOTween.From to set isFrom property. + + + A + + + + + Returns true if at least one property tween was added to these parameters, + either via Prop() or NewProp(). + + + + + Enumeration of types of loops to apply. + + + + + When a tween completes, rewinds the animation and restarts (X to Y, repeat). + + + + + Tweens to the end values then back to the original ones and so on (X to Y, Y to X, repeat). + + + + + Like , but also inverts the easing (meaning if it was easeInSomething, it will become easeOutSomething, and viceversa). + + + + + Continuously increments the tween (X to Y, Y to Y+(Y-X), and so on), + thus always moving "onward". + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a cubic (t^3) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a cubic (t^3) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a cubic (t^3) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a circular (sqrt(1-t^2)) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a circular (sqrt(1-t^2)) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a circular (sqrt(1-t^2)) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + Unused: here to keep same delegate for all ease types. + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). + + + + + Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + Overshoot ammount: higher means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). + + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out: decelerating from zero velocity. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + Overshoot ammount: higher means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). + + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration. + + + Current time (in frames or seconds). + + + Starting value. + + + Change needed in value. + + + Expected easing duration (in frames or seconds). + + + Overshoot ammount: higher means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). + + Unused: here to keep same delegate for all ease types. + + The eased value. + + + + + Plugin for the tweening of the float of your choice. + Used for changing material floats. + Target for this tween must be of type . + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Selects the color property to change. + + + The propertyName/floatName to change (see Unity's if you don't know how it works). + + + + + Overridden by plugins that need a specific type of target, to check it and validate it. + Returns true if the tween target is valid. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Sets the value of the controlled property. + Some plugins (like PlugSetColor) might override this to get values from different properties. + + + The new value. + + + + + Gets the current value of the controlled property. + Some plugins (like PlugSetColor) might override this to set values on different properties. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Default plugin for the tweening of Quaternion objects. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin using the main ease type. + + + The euler angles to tween to. + + + + + Creates a new instance of this plugin. + + + The euler angles to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The euler angles to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The euler angles to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Parameter > Sets rotations to be calculated fully, + and the end value will be reached using the full degrees of the given rotation, even if beyond 360 degrees. + + + + + Parameter > Choose whether you want to calculate angles bigger than 360 degrees or not. + In the first case, the end value will be reached using the full degrees of the given rotation. + In the second case, the end value will be reached from the shortest direction. + If the endValue is set as relative, this option will have no effect, and full beyond 360 rotations will always be used. + + + Set to true to use angles bigger than 360 degrees. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + + Enum of delegates used by HOTween. + + + + + Delegate used to store OnEvent (OnStart, OnComplete, etc) functions that will accept a parameter. + + + + + Delegate used to store OnEvent (OnStart, OnComplete, etc) functions without parameters. + + + + + Delegate used internally for ease functions. + + + + + Used in place of System.Func, which is not available in mscorlib. + + + + + Used in place of System.Action. + + + + + A special class used to setup a "virtual" tween, + which will not actually be tweened nor updated, + but will just set and return a value when you call Update. + + + + + Virtual duration + (you could also set it to 1 or 100 to treat it as a percentage). + + + + + Creates a new TweenVar instance using Linear ease. + + + Start value (FROM). + + + End value (TO). + + + Virtual duration. + (you could also set it to 1 or 100 to treat it as a percentage). + + + + + Creates a new TweenVar instance. + + + Start value (FROM). + + + End value (TO). + + + Virtual duration. + (you could also set it to 1 or 100 to treat it as a percentage). + + + Ease type. + + + + + Creates a new TweenVar instance. + + + Start value (FROM). + + + End value (TO). + + + Virtual duration. + (you could also set it to 1 or 100 to treat it as a percentage). + + + AnimationCurve used for ease. + + + + + Sets and returns the value at which this + would be after the given absolute time. + + + The elapsed time to calculate. + + + + + Sets and returns the value at which this + would be after the given time. + + + The elapsed time to calculate. + + + If true consideres p_elapsed as relative, + meaning it will be added to the previous elapsed time, + otherwise it is considered absolute. + + + + + Start value (FROM). + + + + + End value (TO). + + + + + Ease type. + + + + + Ease type as AnimationCurve. + + + + + The current value of this + + + + + The current elapsed time. + + + + + Method chaining parameters for a . + + + + + Initializes the given with the stored parameters. + + + The to initialize. + + + + + Sets the ID of this Sequence (default = ""). + The same ID can be applied to multiple Sequences, thus allowing for group operations. + You can also use IntId instead of Id for faster operations. + + + The ID for this Sequence. + + + + + Sets the int ID of this Tweener (default = 0). + The same intId can be applied to multiple Tweeners, thus allowing for group operations. + The main difference from Id is that while Id is more legible, IntId allows for faster operations. + + + The int ID for this Tweener. + + + + + Sets auto-kill behaviour for when the Sequence reaches its end (default = false). + + + If true the Sequence is killed and removed from HOTween as soon as it's completed. + If false doesn't remove this Sequence from HOTween when it is completed, + and you will need to call an HOTween.Kill to remove this Sequence. + + + + + Sets the type of update to use for this Sequence (default = .Update). + + + The type of update to use. + + + + + Sets the time scale that will be used by this Sequence. + + + The time scale to use. + + + + + Sets the number of times the Sequence will run (default = 1, meaning only one go and no other loops). + + + Number of loops (set it to -1 or to apply infinite loops). + + + + + Sets the number of times the Sequence will run, + and the type of loop behaviour to apply + (default = 1, LoopType.Restart). + + + Number of loops (set it to -1 or to apply infinite loops). + + + The behaviour to use. + Note the is available, but as an experimental feature. + It works with simple Sequences, but you should check that your animation + works as intended with more complex Sequences. + + + + + Function to call when the Sequence is started for the very first time. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when the Sequence is started for the very first time. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call each time the Sequence is updated. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call each time the Sequence is updated. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call when the Sequence switches from a playing state to a paused state. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when the Sequence switches from a playing state to a paused state. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call when the Sequence switches from a paused state to a playing state. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when the Sequence switches from a paused state to a playing state. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call each time the sequence is rewinded from a non-rewinded state + (either because of a direct call to Rewind, + or because the tween's virtual playehead reached the start due to a playing backwards behaviour). + + + The function to call, who must return void and accept no parameters. + + + + + Function to call each time the sequence is rewinded from a non-rewinded state + (either because of a direct call to Rewind, + or because the tween's virtual playehead reached the start due to a playing backwards behaviour). + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Function to call each time a single loop of the Sequence is completed. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call each time a single loop of the Sequence is completed. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Uses sendMessage to call the method named p_methodName + on every MonoBehaviour in the p_sendMessageTarget GameObject. + + GameObject to target for sendMessage + Name of the method to call + Eventual additional parameter + SendMessageOptions + + + + Function to call when the full Sequence, loops included, is completed. + + + The function to call, who must return void and accept no parameters. + + + + + Function to call when the full Sequence, loops included, is completed. + + + The function to call. + It must return void and has to accept a single parameter of type . + + + Additional comma separated parameters to pass to the function. + + + + + Uses sendMessage to call the method named p_methodName + on every MonoBehaviour in the p_sendMessageTarget GameObject. + + GameObject to target for sendMessage + Name of the method to call + Eventual additional parameter + SendMessageOptions + + + + Keeps the given component enabled while the tween is playing + + + + + Keeps the given gameObject activated while the tween is playing + + + + + Keeps the given components enabled while the tween is playing + + + + + Keeps the given GameObject activated while the tween is playing + + + + + Keeps the given component disabled while the tween is playing + + + + + Keeps the given GameObject disabled while the tween is playing + + + + + Keeps the given components disabled while the tween is playing + + + + + Keeps the given GameObject disabled while the tween is playing + + + + + Plugin for the tweening of number values only through integers. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + + + Creates a new instance of this plugin using the main ease type. + + + The value to tween to. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use. + + + If true, the given end value is considered relative instead than absolute. + + + + + Creates a new instance of this plugin. + + + The value to tween to. + + + The to use for easing. + + + If true, the given end value is considered relative instead than absolute. + + + + + Returns the speed-based duration based on the given speed x second. + + + + + Sets the typed changeVal based on the current startVal and endVal. + + + + + Sets the correct values in case of Incremental loop type. + + + The difference from the previous loop increment. + + + + + Sets the correct values in case of RestartIncremental. + + + + + Updates the tween. + + + The total elapsed time since startup. + + + + + Gets the untyped start value, + sets both the untyped and the typed start value. + + + + + Gets the untyped end value, + sets both the untyped and the typed end value. + + + + diff --git a/Assets/Scripts/HOTween/HOTween.XML.meta b/Assets/Scripts/HOTween/HOTween.XML.meta new file mode 100644 index 0000000..cfca5e2 --- /dev/null +++ b/Assets/Scripts/HOTween/HOTween.XML.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: debacd8a06bcccc4d9ced9108f3761ac +TextScriptImporter: + userData: diff --git a/Assets/Scripts/HOTween/HOTween.dll b/Assets/Scripts/HOTween/HOTween.dll new file mode 100644 index 0000000000000000000000000000000000000000..591d080a5de4051dc60208881b3acdbd53374a92 GIT binary patch literal 109568 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 literal 0 HcmV?d00001 diff --git a/Assets/Scripts/HOTween/HOTween.dll.mdb b/Assets/Scripts/HOTween/HOTween.dll.mdb new file mode 100644 index 0000000000000000000000000000000000000000..d1146dca2db38d560cd499c00759bb141a214482 GIT binary patch literal 55200 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 ZRN-Jg)i{_>4G!j0n}hk(<6u4w`Tyc~6fXb( literal 0 HcmV?d00001 diff --git a/Assets/LuaFramework/Luajit/jit/bc.lua.meta b/Assets/Scripts/HOTween/HOTween.dll.mdb.meta similarity index 56% rename from Assets/LuaFramework/Luajit/jit/bc.lua.meta rename to Assets/Scripts/HOTween/HOTween.dll.mdb.meta index 7b72560..37c10ca 100644 --- a/Assets/LuaFramework/Luajit/jit/bc.lua.meta +++ b/Assets/Scripts/HOTween/HOTween.dll.mdb.meta @@ -1,4 +1,4 @@ fileFormatVersion: 2 -guid: d18ce292c8e9a3446a5890f324daddc8 +guid: 031dfe48fb830014e96aba779328d075 DefaultImporter: userData: diff --git a/Assets/Scripts/HOTween/HOTween.dll.meta b/Assets/Scripts/HOTween/HOTween.dll.meta new file mode 100644 index 0000000..9ff11de --- /dev/null +++ b/Assets/Scripts/HOTween/HOTween.dll.meta @@ -0,0 +1,23 @@ +fileFormatVersion: 2 +guid: 6fd3f0e8d2bb977489d676e4316853f9 +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + DefaultValueInitialized: true + WindowsStoreApps: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/HOTween/HOTween_License.txt b/Assets/Scripts/HOTween/HOTween_License.txt new file mode 100644 index 0000000..42e55f7 --- /dev/null +++ b/Assets/Scripts/HOTween/HOTween_License.txt @@ -0,0 +1,7 @@ +Copyright (c) 2012 Daniele Giardini + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Assets/Scripts/HOTween/HOTween_License.txt.meta b/Assets/Scripts/HOTween/HOTween_License.txt.meta new file mode 100644 index 0000000..37eca03 --- /dev/null +++ b/Assets/Scripts/HOTween/HOTween_License.txt.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 305f88b38f8a12b47bf41452a50d2f71 +TextScriptImporter: + userData: diff --git a/Assets/Scripts/Main.cs b/Assets/Scripts/Main.cs index 55fd7de..39f0c5b 100644 --- a/Assets/Scripts/Main.cs +++ b/Assets/Scripts/Main.cs @@ -1,20 +1,18 @@ using UnityEngine; +using LuaFramework; ///

/// 游戏入口脚本 /// public class Main : MonoBehaviour { - private void Awake() + void Awake() { // 热更新前初始化一些模块 InitBeforeHotUpdate(); - // 预加载基础的Bundle - ResourceMgr.instance.PreloadBaseBundle(); - // 显示更新界面 - HotUpdatePanel.Create(()=> + HotUpdatePanel.Show(()=> { // 热更新后初始化一些模块 InitAfterHotUpdate(); @@ -36,12 +34,22 @@ public class Main : MonoBehaviour /// private void InitBeforeHotUpdate() { + GameLogger.Log("InitBeforeHotUpdate"); + // 限制游戏帧数 + Application.targetFrameRate = AppConst.GameFrameRate; + // 手机常亮// + Screen.sleepTimeout = -1; + // 后台运行// + Application.runInBackground = true; // 日志管理 LogMgr.instance.Init(); // 版本管理 VersionMgr.instance.Init(); // 界面管理 PanelMgr.instance.Init(); + // 预加载assetbundle资源 + AssetBundleMgr.instance.PreloadAssetBundles(); + // TODO 加载必要的资源assetbundle } /// @@ -49,19 +57,31 @@ public class Main : MonoBehaviour /// private void InitAfterHotUpdate() { - Debug.Log("AfterHotUpdate"); - - ResourceCfg.instance.LoadCfg(); - // 预加载Lua的AssetBundle - ResourceMgr.instance.PreloadLuaBundles(); + GameLogger.Log("InitAfterHotUpdate"); // 启动lua框架 AppFacade.Instance.StartUp(); } - private void OnApplicationQuit() + void Update() + { + + } + + void LateUpdate() + { + + } + + void FixedUpdate() + { + AppFacade.Instance.FixedUpdate(); + } + + void OnApplicationQuit() { LogMgr.instance.OnApplicationQuit(); + // 聊天服务器 ClientSocket.instance.CloseSocket(); } } \ No newline at end of file diff --git a/Assets/Scripts/View/HotUpdatePanel.cs b/Assets/Scripts/View/HotUpdatePanel.cs index c4d294d..9d400e3 100644 --- a/Assets/Scripts/View/HotUpdatePanel.cs +++ b/Assets/Scripts/View/HotUpdatePanel.cs @@ -20,17 +20,27 @@ public class HotUpdatePanel : BasePanel private GameObject mErrorTipsDlg; private Text mErrorText; private Button mRetryBtn; + /// + /// 更新完毕后回调 + /// + private Action mCb; - public static void Create(Action hideCb) + public static void Show(Action hideCb) { - var panel = PanelMgr.instance.ShowPanel("HotUpdatePanel", "BaseRes/UpdatePanel.prefab"); - if (null != hideCb) - panel.hideCb = hideCb; + var panel = PanelMgr.instance.ShowPanel(1, GlobalObjs.sTopPanel); + panel.mCb = hideCb; } - void Awake() + protected override void OnShow(Transform parent) { + base.OnShow(parent); + var panelObj = ResourceMgr.instance.Instantiate("BaseRes/HotUpdatePanel.prefab"); var uiBinder = gameObject.GetComponent(); + SetUi(uiBinder); + } + + void SetUi(PrefabObjBinder uiBinder) + { mVersionText = uiBinder.GetObj("versionText"); mProgressSlider = uiBinder.GetObj("progressSlider"); mProgressText = uiBinder.GetObj("progressText"); @@ -135,7 +145,7 @@ public class HotUpdatePanel : BasePanel Finish(); } - private void Update() + protected override void Update() { mHotUpdater.Update(); } @@ -152,8 +162,8 @@ public class HotUpdatePanel : BasePanel private void Finish() { - Destroy(gameObject); - hideCb?.Invoke(); + PanelMgr.instance.HidePanel(1); + mCb?.Invoke(); } private void OnApplicationQuit() -- GitLab