From 362f6dd461781e4ad87612e205e684384773cfb7 Mon Sep 17 00:00:00 2001 From: wsycarlos Date: Sun, 28 Dec 2025 22:33:01 +0800 Subject: [PATCH] Initial Full Package of GameFramework --- .gitignore | 106 + .../Editor.meta | 8 + .../Editor/Inspector.meta | 8 + .../Inspector/BaseComponentInspector.cs | 319 ++ .../Inspector/BaseComponentInspector.cs.meta | 11 + .../Inspector/ConfigComponentInspector.cs | 74 + .../ConfigComponentInspector.cs.meta | 11 + .../Inspector/DataNodeComponentInspector.cs | 51 + .../DataNodeComponentInspector.cs.meta | 11 + .../Inspector/DataTableComponentInspector.cs | 87 + .../DataTableComponentInspector.cs.meta | 11 + .../Inspector/DebuggerComponentInspector.cs | 68 + .../DebuggerComponentInspector.cs.meta | 11 + .../Inspector/DownloadComponentInspector.cs | 156 + .../DownloadComponentInspector.cs.meta | 11 + .../EditorResourceComponentInspector.cs | 52 + .../EditorResourceComponentInspector.cs.meta | 11 + .../Inspector/EntityComponentInspector.cs | 88 + .../EntityComponentInspector.cs.meta | 11 + .../Inspector/EventComponentInspector.cs | 41 + .../Inspector/EventComponentInspector.cs.meta | 11 + .../Inspector/FileSystemComponentInspector.cs | 73 + .../FileSystemComponentInspector.cs.meta | 11 + .../Editor/Inspector/FsmComponentInspector.cs | 53 + .../Inspector/FsmComponentInspector.cs.meta | 11 + .../Inspector/GameFrameworkInspector.cs | 64 + .../Inspector/GameFrameworkInspector.cs.meta | 11 + .../LocalizationComponentInspector.cs | 76 + .../LocalizationComponentInspector.cs.meta | 11 + .../Inspector/NetworkComponentInspector.cs | 76 + .../NetworkComponentInspector.cs.meta | 11 + .../Inspector/ObjectPoolComponentInspector.cs | 138 + .../ObjectPoolComponentInspector.cs.meta | 11 + .../Inspector/ProcedureComponentInspector.cs | 172 ++ .../ProcedureComponentInspector.cs.meta | 11 + .../ReferencePoolComponentInspector.cs | 152 + .../ReferencePoolComponentInspector.cs.meta | 11 + .../Inspector/ResourceComponentInspector.cs | 397 +++ .../ResourceComponentInspector.cs.meta | 11 + .../Inspector/SceneComponentInspector.cs | 75 + .../Inspector/SceneComponentInspector.cs.meta | 11 + .../Inspector/SettingComponentInspector.cs | 81 + .../SettingComponentInspector.cs.meta | 11 + .../Inspector/SoundComponentInspector.cs | 87 + .../Inspector/SoundComponentInspector.cs.meta | 11 + .../Editor/Inspector/UIComponentInspector.cs | 154 + .../Inspector/UIComponentInspector.cs.meta | 11 + .../Inspector/WebRequestComponentInspector.cs | 141 + .../WebRequestComponentInspector.cs.meta | 11 + .../Editor/Misc.meta | 8 + .../Editor/Misc/BuildSettings.cs | 133 + .../Editor/Misc/BuildSettings.cs.meta | 11 + .../Misc/BuildSettingsConfigPathAttribute.cs | 16 + .../BuildSettingsConfigPathAttribute.cs.meta | 11 + .../Editor/Misc/ConfigPathAttribute.cs | 18 + .../Editor/Misc/ConfigPathAttribute.cs.meta | 11 + .../Editor/Misc/Help.cs | 35 + .../Editor/Misc/Help.cs.meta | 11 + .../Editor/Misc/HelperInfo.cs | 97 + .../Editor/Misc/HelperInfo.cs.meta | 11 + .../Editor/Misc/LogRedirection.cs | 122 + .../Editor/Misc/LogRedirection.cs.meta | 11 + .../Editor/Misc/LogScriptingDefineSymbols.cs | 179 ++ .../Misc/LogScriptingDefineSymbols.cs.meta | 11 + .../Editor/Misc/OpenFolder.cs | 91 + .../Editor/Misc/OpenFolder.cs.meta | 11 + .../Editor/Misc/ScriptingDefineSymbols.cs | 157 + .../Misc/ScriptingDefineSymbols.cs.meta | 11 + .../Editor/Misc/Type.cs | 127 + .../Editor/Misc/Type.cs.meta | 11 + .../Editor/ResourceAnalyzer.meta | 8 + .../Editor/ResourceAnalyzer/AssetsOrder.cs | 21 + .../ResourceAnalyzer/AssetsOrder.cs.meta | 11 + .../Editor/ResourceAnalyzer/DependencyData.cs | 96 + .../ResourceAnalyzer/DependencyData.cs.meta | 11 + .../ResourceAnalyzer/ResourceAnalyzer.cs | 533 ++++ .../ResourceAnalyzer/ResourceAnalyzer.cs.meta | 11 + ...zerController.CircularDependencyChecker.cs | 76 + ...ntroller.CircularDependencyChecker.cs.meta | 11 + .../ResourceAnalyzerController.Stamp.cs | 43 + .../ResourceAnalyzerController.Stamp.cs.meta | 11 + .../ResourceAnalyzerController.cs | 324 ++ .../ResourceAnalyzerController.cs.meta | 11 + .../ResourceAnalyzer/ScatteredAssetsOrder.cs | 17 + .../ScatteredAssetsOrder.cs.meta | 11 + .../Editor/ResourceBuilder.meta | 8 + .../AssetBundleCompressionType.cs | 30 + .../AssetBundleCompressionType.cs.meta | 11 + .../ResourceBuilder/IBuildEventHandler.cs | 138 + .../IBuildEventHandler.cs.meta | 11 + .../Editor/ResourceBuilder/Platform.cs | 57 + .../Editor/ResourceBuilder/Platform.cs.meta | 11 + .../Editor/ResourceBuilder/ResourceBuilder.cs | 513 ++++ .../ResourceBuilder/ResourceBuilder.cs.meta | 11 + .../ResourceBuilderConfigPathAttribute.cs | 16 + ...ResourceBuilderConfigPathAttribute.cs.meta | 11 + .../ResourceBuilderController.AssetData.cs | 67 + ...esourceBuilderController.AssetData.cs.meta | 11 + .../ResourceBuilderController.BuildReport.cs | 276 ++ ...ourceBuilderController.BuildReport.cs.meta | 11 + ...ourceBuilderController.FileSystemHelper.cs | 22 + ...BuilderController.FileSystemHelper.cs.meta | 11 + .../ResourceBuilderController.ResourceCode.cs | 70 + ...urceBuilderController.ResourceCode.cs.meta | 11 + .../ResourceBuilderController.ResourceData.cs | 167 + ...urceBuilderController.ResourceData.cs.meta | 11 + ...sourceBuilderController.VersionListData.cs | 54 + ...eBuilderController.VersionListData.cs.meta | 11 + .../ResourceBuilderController.cs | 1567 ++++++++++ .../ResourceBuilderController.cs.meta | 11 + .../Editor/ResourceCollection.meta | 8 + .../Editor/ResourceCollection/Asset.cs | 59 + .../Editor/ResourceCollection/Asset.cs.meta | 11 + .../Editor/ResourceCollection/AssetType.cs | 30 + .../ResourceCollection/AssetType.cs.meta | 11 + .../Editor/ResourceCollection/LoadType.cs | 50 + .../ResourceCollection/LoadType.cs.meta | 11 + .../Editor/ResourceCollection/Resource.cs | 192 ++ .../ResourceCollection/Resource.cs.meta | 11 + .../ResourceCollection/ResourceCollection.cs | 635 ++++ .../ResourceCollection.cs.meta | 11 + .../ResourceCollectionConfigPathAttribute.cs | 16 + ...ourceCollectionConfigPathAttribute.cs.meta | 11 + .../Editor/ResourceEditor.meta | 8 + .../Editor/ResourceEditor/AssetSorterType.cs | 16 + .../ResourceEditor/AssetSorterType.cs.meta | 11 + .../ResourceEditor.MenuState.cs | 22 + .../ResourceEditor.MenuState.cs.meta | 11 + .../ResourceEditor.ResourceFolder.cs | 164 + .../ResourceEditor.ResourceFolder.cs.meta | 11 + .../ResourceEditor.ResourceItem.cs | 159 + .../ResourceEditor.ResourceItem.cs.meta | 11 + .../Editor/ResourceEditor/ResourceEditor.cs | 1120 +++++++ .../ResourceEditor/ResourceEditor.cs.meta | 11 + .../ResourceEditorConfigPathAttribute.cs | 16 + .../ResourceEditorConfigPathAttribute.cs.meta | 11 + .../ResourceEditorController.cs | 679 ++++ .../ResourceEditorController.cs.meta | 11 + .../Editor/ResourceEditor/SourceAsset.cs | 85 + .../Editor/ResourceEditor/SourceAsset.cs.meta | 11 + .../Editor/ResourceEditor/SourceFolder.cs | 172 ++ .../ResourceEditor/SourceFolder.cs.meta | 11 + .../Editor/ResourcePackBuilder.meta | 8 + .../ResourcePackBuilder.cs | 487 +++ .../ResourcePackBuilder.cs.meta | 11 + .../ResourcePackBuilderController.cs | 558 ++++ .../ResourcePackBuilderController.cs.meta | 11 + .../Editor/ResourceSyncTools.meta | 8 + .../ResourceSyncTools/ResourceSyncTools.cs | 115 + .../ResourceSyncTools.cs.meta | 11 + .../ResourceSyncToolsController.cs | 229 ++ .../ResourceSyncToolsController.cs.meta | 11 + .../Editor/UnityGameFrameworkEditor.asmdef | 19 + .../UnityGameFrameworkEditor.asmdef.meta | 7 + .../Runtime.meta | 8 + .../Runtime/GameFramework.meta | 8 + .../Runtime/GameFramework/Base.meta | 8 + .../GameFramework/Base/DataProvider.meta | 8 + .../Base/DataProvider/DataProvider.cs | 500 +++ .../Base/DataProvider/DataProvider.cs.meta | 11 + .../Base/DataProvider/DataProviderCreator.cs | 77 + .../DataProvider/DataProviderCreator.cs.meta | 11 + .../Base/DataProvider/IDataProvider.cs | 115 + .../Base/DataProvider/IDataProvider.cs.meta | 11 + .../Base/DataProvider/IDataProviderHelper.cs | 64 + .../DataProvider/IDataProviderHelper.cs.meta | 11 + .../ReadDataDependencyAssetEventArgs.cs | 104 + .../ReadDataDependencyAssetEventArgs.cs.meta | 11 + .../DataProvider/ReadDataFailureEventArgs.cs | 78 + .../ReadDataFailureEventArgs.cs.meta | 11 + .../DataProvider/ReadDataSuccessEventArgs.cs | 78 + .../ReadDataSuccessEventArgs.cs.meta | 11 + .../DataProvider/ReadDataUpdateEventArgs.cs | 78 + .../ReadDataUpdateEventArgs.cs.meta | 11 + .../GameFramework/Base/DataStruct.meta | 8 + .../Base/DataStruct/TypeNamePair.cs | 135 + .../Base/DataStruct/TypeNamePair.cs.meta | 11 + .../Runtime/GameFramework/Base/EventPool.meta | 8 + .../Base/EventPool/BaseEventArgs.cs | 23 + .../Base/EventPool/BaseEventArgs.cs.meta | 11 + .../Base/EventPool/EventPool.Event.cs | 57 + .../Base/EventPool/EventPool.Event.cs.meta | 11 + .../GameFramework/Base/EventPool/EventPool.cs | 285 ++ .../Base/EventPool/EventPool.cs.meta | 11 + .../Base/EventPool/EventPoolMode.cs | 38 + .../Base/EventPool/EventPoolMode.cs.meta | 11 + .../GameFramework/Base/GameFrameworkAction.cs | 366 +++ .../Base/GameFrameworkAction.cs.meta | 11 + .../GameFramework/Base/GameFrameworkEntry.cs | 133 + .../Base/GameFrameworkEntry.cs.meta | 11 + .../Base/GameFrameworkEventArgs.cs | 29 + .../Base/GameFrameworkEventArgs.cs.meta | 11 + .../Base/GameFrameworkException.cs | 56 + .../Base/GameFrameworkException.cs.meta | 11 + .../GameFramework/Base/GameFrameworkFunc.cs | 400 +++ .../Base/GameFrameworkFunc.cs.meta | 11 + .../Base/GameFrameworkLinkedList.cs | 453 +++ .../Base/GameFrameworkLinkedList.cs.meta | 11 + .../Base/GameFrameworkLinkedListRange.cs | 217 ++ .../Base/GameFrameworkLinkedListRange.cs.meta | 11 + .../GameFramework/Base/GameFrameworkModule.cs | 39 + .../Base/GameFrameworkModule.cs.meta | 11 + .../Base/GameFrameworkMultiDictionary.cs | 283 ++ .../Base/GameFrameworkMultiDictionary.cs.meta | 11 + .../Base/GameFrameworkSerializer.cs | 208 ++ .../Base/GameFrameworkSerializer.cs.meta | 11 + .../Runtime/GameFramework/Base/Log.meta | 8 + .../Base/Log/GameFrameworkLog.ILogHelper.cs | 25 + .../Log/GameFrameworkLog.ILogHelper.cs.meta | 11 + .../Base/Log/GameFrameworkLog.cs | 2646 ++++++++++++++++ .../Base/Log/GameFrameworkLog.cs.meta | 11 + .../Base/Log/GameFrameworkLogLevel.cs | 40 + .../Base/Log/GameFrameworkLogLevel.cs.meta | 11 + .../GameFramework/Base/ReferencePool.meta | 8 + .../Base/ReferencePool/IReference.cs | 20 + .../Base/ReferencePool/IReference.cs.meta | 11 + .../ReferencePool.ReferenceCollection.cs | 202 ++ .../ReferencePool.ReferenceCollection.cs.meta | 11 + .../Base/ReferencePool/ReferencePool.cs | 225 ++ .../Base/ReferencePool/ReferencePool.cs.meta | 11 + .../Base/ReferencePool/ReferencePoolInfo.cs | 125 + .../ReferencePool/ReferencePoolInfo.cs.meta | 11 + .../Runtime/GameFramework/Base/TaskPool.meta | 8 + .../GameFramework/Base/TaskPool/ITaskAgent.cs | 53 + .../Base/TaskPool/ITaskAgent.cs.meta | 11 + .../Base/TaskPool/StartTaskStatus.cs | 35 + .../Base/TaskPool/StartTaskStatus.cs.meta | 11 + .../GameFramework/Base/TaskPool/TaskBase.cs | 137 + .../Base/TaskPool/TaskBase.cs.meta | 11 + .../GameFramework/Base/TaskPool/TaskInfo.cs | 153 + .../Base/TaskPool/TaskInfo.cs.meta | 11 + .../GameFramework/Base/TaskPool/TaskPool.cs | 444 +++ .../Base/TaskPool/TaskPool.cs.meta | 11 + .../GameFramework/Base/TaskPool/TaskStatus.cs | 30 + .../Base/TaskPool/TaskStatus.cs.meta | 11 + .../Runtime/GameFramework/Base/Variable.meta | 8 + .../Base/Variable/GenericVariable.cs | 89 + .../Base/Variable/GenericVariable.cs.meta | 11 + .../GameFramework/Base/Variable/Variable.cs | 49 + .../Base/Variable/Variable.cs.meta | 11 + .../Runtime/GameFramework/Base/Version.meta | 8 + .../Base/Version/Version.IVersionHelper.cs | 34 + .../Version/Version.IVersionHelper.cs.meta | 11 + .../GameFramework/Base/Version/Version.cs | 71 + .../Base/Version/Version.cs.meta | 11 + .../Runtime/GameFramework/Config.meta | 8 + .../Config/ConfigManager.ConfigData.cs | 63 + .../Config/ConfigManager.ConfigData.cs.meta | 11 + .../GameFramework/Config/ConfigManager.cs | 487 +++ .../Config/ConfigManager.cs.meta | 11 + .../GameFramework/Config/IConfigHelper.cs | 16 + .../Config/IConfigHelper.cs.meta | 11 + .../GameFramework/Config/IConfigManager.cs | 160 + .../Config/IConfigManager.cs.meta | 11 + .../Runtime/GameFramework/DataNode.meta | 8 + .../DataNode/DataNodeManager.DataNode.cs | 383 +++ .../DataNode/DataNodeManager.DataNode.cs.meta | 11 + .../GameFramework/DataNode/DataNodeManager.cs | 280 ++ .../DataNode/DataNodeManager.cs.meta | 11 + .../GameFramework/DataNode/IDataNode.cs | 151 + .../GameFramework/DataNode/IDataNode.cs.meta | 11 + .../DataNode/IDataNodeManager.cs | 135 + .../DataNode/IDataNodeManager.cs.meta | 11 + .../Runtime/GameFramework/DataTable.meta | 8 + .../GameFramework/DataTable/DataTableBase.cs | 304 ++ .../DataTable/DataTableBase.cs.meta | 11 + .../DataTable/DataTableManager.DataTable.cs | 524 ++++ .../DataTableManager.DataTable.cs.meta | 11 + .../DataTable/DataTableManager.cs | 508 +++ .../DataTable/DataTableManager.cs.meta | 11 + .../GameFramework/DataTable/IDataRow.cs | 41 + .../GameFramework/DataTable/IDataRow.cs.meta | 11 + .../GameFramework/DataTable/IDataTable.cs | 192 ++ .../DataTable/IDataTable.cs.meta | 11 + .../DataTable/IDataTableHelper.cs | 16 + .../DataTable/IDataTableHelper.cs.meta | 11 + .../DataTable/IDataTableManager.cs | 211 ++ .../DataTable/IDataTableManager.cs.meta | 11 + .../Runtime/GameFramework/Debugger.meta | 8 + .../DebuggerManager.DebuggerWindowGroup.cs | 307 ++ ...ebuggerManager.DebuggerWindowGroup.cs.meta | 11 + .../GameFramework/Debugger/DebuggerManager.cs | 141 + .../Debugger/DebuggerManager.cs.meta | 11 + .../Debugger/IDebuggerManager.cs | 61 + .../Debugger/IDebuggerManager.cs.meta | 11 + .../GameFramework/Debugger/IDebuggerWindow.cs | 48 + .../Debugger/IDebuggerWindow.cs.meta | 11 + .../Debugger/IDebuggerWindowGroup.cs | 59 + .../Debugger/IDebuggerWindowGroup.cs.meta | 11 + .../Runtime/GameFramework/Download.meta | 8 + .../GameFramework/Download/Constant.cs | 20 + .../GameFramework/Download/Constant.cs.meta | 11 + .../DownloadAgentHelperCompleteEventArgs.cs | 57 + ...wnloadAgentHelperCompleteEventArgs.cs.meta | 11 + .../DownloadAgentHelperErrorEventArgs.cs | 65 + .../DownloadAgentHelperErrorEventArgs.cs.meta | 11 + ...DownloadAgentHelperUpdateBytesEventArgs.cs | 94 + ...oadAgentHelperUpdateBytesEventArgs.cs.meta | 11 + ...ownloadAgentHelperUpdateLengthEventArgs.cs | 57 + ...adAgentHelperUpdateLengthEventArgs.cs.meta | 11 + .../Download/DownloadFailureEventArgs.cs | 104 + .../Download/DownloadFailureEventArgs.cs.meta | 11 + .../Download/DownloadManager.DownloadAgent.cs | 375 +++ .../DownloadManager.DownloadAgent.cs.meta | 11 + ...ger.DownloadCounter.DownloadCounterNode.cs | 64 + ...ownloadCounter.DownloadCounterNode.cs.meta | 11 + .../DownloadManager.DownloadCounter.cs | 170 + .../DownloadManager.DownloadCounter.cs.meta | 11 + .../Download/DownloadManager.DownloadTask.cs | 143 + .../DownloadManager.DownloadTask.cs.meta | 11 + .../DownloadManager.DownloadTaskStatus.cs | 38 + ...DownloadManager.DownloadTaskStatus.cs.meta | 11 + .../GameFramework/Download/DownloadManager.cs | 486 +++ .../Download/DownloadManager.cs.meta | 11 + .../Download/DownloadStartEventArgs.cs | 104 + .../Download/DownloadStartEventArgs.cs.meta | 11 + .../Download/DownloadSuccessEventArgs.cs | 104 + .../Download/DownloadSuccessEventArgs.cs.meta | 11 + .../Download/DownloadUpdateEventArgs.cs | 104 + .../Download/DownloadUpdateEventArgs.cs.meta | 11 + .../Download/IDownloadAgentHelper.cs | 66 + .../Download/IDownloadAgentHelper.cs.meta | 11 + .../Download/IDownloadManager.cs | 240 ++ .../Download/IDownloadManager.cs.meta | 11 + .../Runtime/GameFramework/Entity.meta | 8 + .../Entity/EntityManager.EntityGroup.cs | 394 +++ .../Entity/EntityManager.EntityGroup.cs.meta | 11 + .../Entity/EntityManager.EntityInfo.cs | 136 + .../Entity/EntityManager.EntityInfo.cs.meta | 11 + .../EntityManager.EntityInstanceObject.cs | 60 + ...EntityManager.EntityInstanceObject.cs.meta | 11 + .../Entity/EntityManager.EntityStatus.cs | 28 + .../Entity/EntityManager.EntityStatus.cs.meta | 11 + .../Entity/EntityManager.ShowEntityInfo.cs | 78 + .../EntityManager.ShowEntityInfo.cs.meta | 11 + .../GameFramework/Entity/EntityManager.cs | 1327 ++++++++ .../Entity/EntityManager.cs.meta | 11 + .../Entity/HideEntityCompleteEventArgs.cs | 91 + .../HideEntityCompleteEventArgs.cs.meta | 11 + .../Runtime/GameFramework/Entity/IEntity.cs | 110 + .../GameFramework/Entity/IEntity.cs.meta | 11 + .../GameFramework/Entity/IEntityGroup.cs | 145 + .../GameFramework/Entity/IEntityGroup.cs.meta | 11 + .../Entity/IEntityGroupHelper.cs | 16 + .../Entity/IEntityGroupHelper.cs.meta | 11 + .../GameFramework/Entity/IEntityHelper.cs | 38 + .../Entity/IEntityHelper.cs.meta | 11 + .../GameFramework/Entity/IEntityManager.cs | 450 +++ .../Entity/IEntityManager.cs.meta | 11 + .../ShowEntityDependencyAssetEventArgs.cs | 130 + ...ShowEntityDependencyAssetEventArgs.cs.meta | 11 + .../Entity/ShowEntityFailureEventArgs.cs | 104 + .../Entity/ShowEntityFailureEventArgs.cs.meta | 11 + .../Entity/ShowEntitySuccessEventArgs.cs | 78 + .../Entity/ShowEntitySuccessEventArgs.cs.meta | 11 + .../Entity/ShowEntityUpdateEventArgs.cs | 104 + .../Entity/ShowEntityUpdateEventArgs.cs.meta | 11 + .../Runtime/GameFramework/Event.meta | 8 + .../GameFramework/Event/EventManager.cs | 149 + .../GameFramework/Event/EventManager.cs.meta | 11 + .../GameFramework/Event/GameEventArgs.cs | 16 + .../GameFramework/Event/GameEventArgs.cs.meta | 11 + .../GameFramework/Event/IEventManager.cs | 82 + .../GameFramework/Event/IEventManager.cs.meta | 11 + .../Runtime/GameFramework/FileSystem.meta | 8 + .../FileSystem/CommonFileSystemStream.cs | 162 + .../FileSystem/CommonFileSystemStream.cs.meta | 11 + .../GameFramework/FileSystem/FileInfo.cs | 94 + .../GameFramework/FileSystem/FileInfo.cs.meta | 11 + .../FileSystem/FileSystem.BlockData.cs | 76 + .../FileSystem/FileSystem.BlockData.cs.meta | 11 + .../FileSystem/FileSystem.HeaderData.cs | 105 + .../FileSystem/FileSystem.HeaderData.cs.meta | 11 + .../FileSystem/FileSystem.StringData.cs | 70 + .../FileSystem/FileSystem.StringData.cs.meta | 11 + .../GameFramework/FileSystem/FileSystem.cs | 1381 +++++++++ .../FileSystem/FileSystem.cs.meta | 11 + .../FileSystem/FileSystemAccess.cs | 38 + .../FileSystem/FileSystemAccess.cs.meta | 11 + .../FileSystem/FileSystemManager.cs | 283 ++ .../FileSystem/FileSystemManager.cs.meta | 11 + .../FileSystem/FileSystemStream.cs | 135 + .../FileSystem/FileSystemStream.cs.meta | 11 + .../GameFramework/FileSystem/IFileSystem.cs | 277 ++ .../FileSystem/IFileSystem.cs.meta | 11 + .../FileSystem/IFileSystemHelper.cs | 24 + .../FileSystem/IFileSystemHelper.cs.meta | 11 + .../FileSystem/IFileSystemManager.cs | 82 + .../FileSystem/IFileSystemManager.cs.meta | 11 + .../Runtime/GameFramework/Fsm.meta | 8 + .../Runtime/GameFramework/Fsm/Fsm.cs | 588 ++++ .../Runtime/GameFramework/Fsm/Fsm.cs.meta | 11 + .../Runtime/GameFramework/Fsm/FsmBase.cs | 113 + .../Runtime/GameFramework/Fsm/FsmBase.cs.meta | 11 + .../Runtime/GameFramework/Fsm/FsmManager.cs | 411 +++ .../GameFramework/Fsm/FsmManager.cs.meta | 11 + .../Runtime/GameFramework/Fsm/FsmState.cs | 110 + .../GameFramework/Fsm/FsmState.cs.meta | 11 + .../Runtime/GameFramework/Fsm/IFsm.cs | 179 ++ .../Runtime/GameFramework/Fsm/IFsm.cs.meta | 11 + .../Runtime/GameFramework/Fsm/IFsmManager.cs | 181 ++ .../GameFramework/Fsm/IFsmManager.cs.meta | 11 + .../GameFramework/GameFramework.asmdef | 14 + .../GameFramework/GameFramework.asmdef.meta | 7 + .../Runtime/GameFramework/Libraries.meta | 8 + .../Libraries/ICSharpCode.SharpZipLib.dll | Bin 0 -> 200704 bytes .../ICSharpCode.SharpZipLib.dll.meta | 33 + .../Runtime/GameFramework/Libraries/link.xml | 41 + .../GameFramework/Libraries/link.xml.meta | 7 + .../Runtime/GameFramework/Localization.meta | 8 + .../Localization/ILocalizationHelper.cs | 23 + .../Localization/ILocalizationHelper.cs.meta | 11 + .../Localization/ILocalizationManager.cs | 504 +++ .../Localization/ILocalizationManager.cs.meta | 11 + .../GameFramework/Localization/Language.cs | 270 ++ .../Localization/Language.cs.meta | 11 + .../Localization/LocalizationManager.cs | 1065 +++++++ .../Localization/LocalizationManager.cs.meta | 11 + .../Runtime/GameFramework/Network.meta | 8 + .../GameFramework/Network/AddressFamily.cs | 30 + .../Network/AddressFamily.cs.meta | 11 + .../GameFramework/Network/INetworkChannel.cs | 164 + .../Network/INetworkChannel.cs.meta | 11 + .../Network/INetworkChannelHelper.cs | 73 + .../Network/INetworkChannelHelper.cs.meta | 11 + .../GameFramework/Network/INetworkManager.cs | 93 + .../Network/INetworkManager.cs.meta | 11 + .../GameFramework/Network/IPacketHandler.cs | 30 + .../Network/IPacketHandler.cs.meta | 11 + .../GameFramework/Network/IPacketHeader.cs | 23 + .../Network/IPacketHeader.cs.meta | 11 + .../Network/NetworkClosedEventArgs.cs | 52 + .../Network/NetworkClosedEventArgs.cs.meta | 11 + .../Network/NetworkConnectedEventArgs.cs | 65 + .../Network/NetworkConnectedEventArgs.cs.meta | 11 + .../Network/NetworkCustomErrorEventArgs.cs | 65 + .../NetworkCustomErrorEventArgs.cs.meta | 11 + .../GameFramework/Network/NetworkErrorCode.cs | 60 + .../Network/NetworkErrorCode.cs.meta | 11 + .../Network/NetworkErrorEventArgs.cs | 93 + .../Network/NetworkErrorEventArgs.cs.meta | 11 + .../Network/NetworkManager.ConnectState.cs | 42 + .../NetworkManager.ConnectState.cs.meta | 11 + .../Network/NetworkManager.HeartBeatState.cs | 58 + .../NetworkManager.HeartBeatState.cs.meta | 11 + .../NetworkManager.NetworkChannelBase.cs | 636 ++++ .../NetworkManager.NetworkChannelBase.cs.meta | 11 + .../Network/NetworkManager.ReceiveState.cs | 98 + .../NetworkManager.ReceiveState.cs.meta | 11 + .../Network/NetworkManager.SendState.cs | 67 + .../Network/NetworkManager.SendState.cs.meta | 11 + .../NetworkManager.TcpNetworkChannel.cs | 290 ++ .../NetworkManager.TcpNetworkChannel.cs.meta | 11 + ...anager.TcpWithSyncReceiveNetworkChannel.cs | 266 ++ ...r.TcpWithSyncReceiveNetworkChannel.cs.meta | 11 + .../GameFramework/Network/NetworkManager.cs | 353 +++ .../Network/NetworkManager.cs.meta | 11 + .../Network/NetworkMissHeartBeatEventArgs.cs | 65 + .../NetworkMissHeartBeatEventArgs.cs.meta | 11 + .../Runtime/GameFramework/Network/Packet.cs | 16 + .../GameFramework/Network/Packet.cs.meta | 11 + .../GameFramework/Network/ServiceType.cs | 25 + .../GameFramework/Network/ServiceType.cs.meta | 11 + .../Runtime/GameFramework/ObjectPool.meta | 8 + .../GameFramework/ObjectPool/IObjectPool.cs | 218 ++ .../ObjectPool/IObjectPool.cs.meta | 11 + .../ObjectPool/IObjectPoolManager.cs | 751 +++++ .../ObjectPool/IObjectPoolManager.cs.meta | 11 + .../GameFramework/ObjectPool/ObjectBase.cs | 207 ++ .../ObjectPool/ObjectBase.cs.meta | 11 + .../GameFramework/ObjectPool/ObjectInfo.cs | 122 + .../ObjectPool/ObjectInfo.cs.meta | 11 + .../ObjectPool/ObjectPoolBase.cs | 152 + .../ObjectPool/ObjectPoolBase.cs.meta | 11 + .../ObjectPool/ObjectPoolManager.Object.cs | 196 ++ .../ObjectPoolManager.Object.cs.meta | 11 + .../ObjectPoolManager.ObjectPool.cs | 637 ++++ .../ObjectPoolManager.ObjectPool.cs.meta | 11 + .../ObjectPool/ObjectPoolManager.cs | 1303 ++++++++ .../ObjectPool/ObjectPoolManager.cs.meta | 11 + .../ObjectPool/ReleaseObjectFilterCallback.cs | 22 + .../ReleaseObjectFilterCallback.cs.meta | 11 + .../Runtime/GameFramework/Procedure.meta | 8 + .../Procedure/IProcedureManager.cs | 81 + .../Procedure/IProcedureManager.cs.meta | 11 + .../GameFramework/Procedure/ProcedureBase.cs | 66 + .../Procedure/ProcedureBase.cs.meta | 11 + .../Procedure/ProcedureManager.cs | 204 ++ .../Procedure/ProcedureManager.cs.meta | 11 + .../Runtime/GameFramework/Properties.meta | 8 + .../GameFramework/Properties/AssemblyInfo.cs | 38 + .../Properties/AssemblyInfo.cs.meta | 11 + .../Runtime/GameFramework/Resource.meta | 8 + .../ApplyResourcesCompleteCallback.cs | 16 + .../ApplyResourcesCompleteCallback.cs.meta | 11 + .../CheckResourcesCompleteCallback.cs | 19 + .../CheckResourcesCompleteCallback.cs.meta | 11 + .../Resource/CheckVersionListResult.cs | 25 + .../Resource/CheckVersionListResult.cs.meta | 11 + .../GameFramework/Resource/Constant.cs | 20 + .../GameFramework/Resource/Constant.cs.meta | 11 + .../Resource/DecryptResourceCallback.cs | 25 + .../Resource/DecryptResourceCallback.cs.meta | 11 + .../GameFramework/Resource/HasAssetResult.cs | 45 + .../Resource/HasAssetResult.cs.meta | 11 + .../Resource/ILoadResourceAgentHelper.cs | 94 + .../Resource/ILoadResourceAgentHelper.cs.meta | 11 + .../GameFramework/Resource/IResourceGroup.cs | 101 + .../Resource/IResourceGroup.cs.meta | 11 + .../Resource/IResourceGroupCollection.cs | 99 + .../Resource/IResourceGroupCollection.cs.meta | 11 + .../GameFramework/Resource/IResourceHelper.cs | 37 + .../Resource/IResourceHelper.cs.meta | 11 + .../Resource/IResourceManager.cs | 832 +++++ .../Resource/IResourceManager.cs.meta | 11 + .../Resource/InitResourcesCompleteCallback.cs | 14 + .../InitResourcesCompleteCallback.cs.meta | 11 + .../Resource/LoadAssetCallbacks.cs | 145 + .../Resource/LoadAssetCallbacks.cs.meta | 11 + .../LoadAssetDependencyAssetCallback.cs | 19 + .../LoadAssetDependencyAssetCallback.cs.meta | 11 + .../Resource/LoadAssetFailureCallback.cs | 18 + .../Resource/LoadAssetFailureCallback.cs.meta | 11 + .../Resource/LoadAssetSuccessCallback.cs | 18 + .../Resource/LoadAssetSuccessCallback.cs.meta | 11 + .../Resource/LoadAssetUpdateCallback.cs | 17 + .../Resource/LoadAssetUpdateCallback.cs.meta | 11 + .../Resource/LoadBinaryCallbacks.cs | 65 + .../Resource/LoadBinaryCallbacks.cs.meta | 11 + .../Resource/LoadBinaryFailureCallback.cs | 18 + .../LoadBinaryFailureCallback.cs.meta | 11 + .../Resource/LoadBinarySuccessCallback.cs | 18 + .../LoadBinarySuccessCallback.cs.meta | 11 + .../Resource/LoadBytesCallbacks.cs | 65 + .../Resource/LoadBytesCallbacks.cs.meta | 11 + .../Resource/LoadBytesFailureCallback.cs | 17 + .../Resource/LoadBytesFailureCallback.cs.meta | 11 + .../Resource/LoadBytesSuccessCallback.cs | 18 + .../Resource/LoadBytesSuccessCallback.cs.meta | 11 + .../LoadResourceAgentHelperErrorEventArgs.cs | 65 + ...dResourceAgentHelperErrorEventArgs.cs.meta | 11 + ...esourceAgentHelperLoadCompleteEventArgs.cs | 52 + ...ceAgentHelperLoadCompleteEventArgs.cs.meta | 11 + ...eAgentHelperParseBytesCompleteEventArgs.cs | 52 + ...tHelperParseBytesCompleteEventArgs.cs.meta | 11 + ...ceAgentHelperReadBytesCompleteEventArgs.cs | 54 + ...ntHelperReadBytesCompleteEventArgs.cs.meta | 11 + ...rceAgentHelperReadFileCompleteEventArgs.cs | 52 + ...entHelperReadFileCompleteEventArgs.cs.meta | 11 + .../LoadResourceAgentHelperUpdateEventArgs.cs | 65 + ...ResourceAgentHelperUpdateEventArgs.cs.meta | 11 + .../Resource/LoadResourceProgress.cs | 40 + .../Resource/LoadResourceProgress.cs.meta | 11 + .../Resource/LoadResourceStatus.cs | 45 + .../Resource/LoadResourceStatus.cs.meta | 11 + .../Resource/LoadSceneCallbacks.cs | 145 + .../Resource/LoadSceneCallbacks.cs.meta | 11 + .../LoadSceneDependencyAssetCallback.cs | 19 + .../LoadSceneDependencyAssetCallback.cs.meta | 11 + .../Resource/LoadSceneFailureCallback.cs | 18 + .../Resource/LoadSceneFailureCallback.cs.meta | 11 + .../Resource/LoadSceneSuccessCallback.cs | 17 + .../Resource/LoadSceneSuccessCallback.cs.meta | 11 + .../Resource/LoadSceneUpdateCallback.cs | 17 + .../Resource/LoadSceneUpdateCallback.cs.meta | 11 + .../Resource/LocalVersionList.FileSystem.cs | 62 + .../LocalVersionList.FileSystem.cs.meta | 11 + .../Resource/LocalVersionList.Resource.cs | 118 + .../LocalVersionList.Resource.cs.meta | 11 + .../Resource/LocalVersionList.cs | 76 + .../Resource/LocalVersionList.cs.meta | 11 + .../Resource/PackageVersionList.Asset.cs | 62 + .../Resource/PackageVersionList.Asset.cs.meta | 11 + .../Resource/PackageVersionList.FileSystem.cs | 62 + .../PackageVersionList.FileSystem.cs.meta | 11 + .../Resource/PackageVersionList.Resource.cs | 132 + .../PackageVersionList.Resource.cs.meta | 11 + .../PackageVersionList.ResourceGroup.cs | 62 + .../PackageVersionList.ResourceGroup.cs.meta | 11 + .../Resource/PackageVersionList.cs | 150 + .../Resource/PackageVersionList.cs.meta | 11 + .../Resource/PackageVersionListSerializer.cs | 33 + .../PackageVersionListSerializer.cs.meta | 11 + .../Resource/ReadOnlyVersionListSerializer.cs | 33 + .../ReadOnlyVersionListSerializer.cs.meta | 11 + .../ReadWriteVersionListSerializer.cs | 33 + .../ReadWriteVersionListSerializer.cs.meta | 11 + .../Resource/ResourceApplyFailureEventArgs.cs | 78 + .../ResourceApplyFailureEventArgs.cs.meta | 11 + .../Resource/ResourceApplyStartEventArgs.cs | 78 + .../ResourceApplyStartEventArgs.cs.meta | 11 + .../Resource/ResourceApplySuccessEventArgs.cs | 104 + .../ResourceApplySuccessEventArgs.cs.meta | 11 + .../Resource/ResourceManager.AssetInfo.cs | 66 + .../ResourceManager.AssetInfo.cs.meta | 11 + .../Resource/ResourceManager.LoadType.cs | 53 + .../Resource/ResourceManager.LoadType.cs.meta | 11 + .../ResourceManager.ReadWriteResourceInfo.cs | 71 + ...ourceManager.ReadWriteResourceInfo.cs.meta | 11 + ...r.ResourceChecker.CheckInfo.CheckStatus.cs | 54 + ...ourceChecker.CheckInfo.CheckStatus.cs.meta | 11 + ...ourceChecker.CheckInfo.LocalVersionInfo.cs | 90 + ...Checker.CheckInfo.LocalVersionInfo.cs.meta | 11 + ...urceChecker.CheckInfo.RemoteVersionInfo.cs | 110 + ...hecker.CheckInfo.RemoteVersionInfo.cs.meta | 11 + ...sourceManager.ResourceChecker.CheckInfo.cs | 294 ++ ...eManager.ResourceChecker.CheckInfo.cs.meta | 11 + .../ResourceManager.ResourceChecker.cs | 505 +++ .../ResourceManager.ResourceChecker.cs.meta | 11 + .../Resource/ResourceManager.ResourceGroup.cs | 268 ++ .../ResourceManager.ResourceGroup.cs.meta | 11 + ...ResourceManager.ResourceGroupCollection.cs | 253 ++ ...rceManager.ResourceGroupCollection.cs.meta | 11 + .../Resource/ResourceManager.ResourceInfo.cs | 168 + .../ResourceManager.ResourceInfo.cs.meta | 11 + .../ResourceManager.ResourceIniter.cs | 181 ++ .../ResourceManager.ResourceIniter.cs.meta | 11 + ...ourceManager.ResourceLoader.AssetObject.cs | 141 + ...Manager.ResourceLoader.AssetObject.cs.meta | 11 + ...rceManager.ResourceLoader.LoadAssetTask.cs | 88 + ...nager.ResourceLoader.LoadAssetTask.cs.meta | 11 + ...ceManager.ResourceLoader.LoadBinaryInfo.cs | 81 + ...ager.ResourceLoader.LoadBinaryInfo.cs.meta | 11 + ....ResourceLoader.LoadDependencyAssetTask.cs | 60 + ...urceLoader.LoadDependencyAssetTask.cs.meta | 11 + ...anager.ResourceLoader.LoadResourceAgent.cs | 361 +++ ...r.ResourceLoader.LoadResourceAgent.cs.meta | 11 + ...ger.ResourceLoader.LoadResourceTaskBase.cs | 176 ++ ...esourceLoader.LoadResourceTaskBase.cs.meta | 11 + ...rceManager.ResourceLoader.LoadSceneTask.cs | 86 + ...nager.ResourceLoader.LoadSceneTask.cs.meta | 11 + ...ceManager.ResourceLoader.ResourceObject.cs | 125 + ...ager.ResourceLoader.ResourceObject.cs.meta | 11 + .../ResourceManager.ResourceLoader.cs | 943 ++++++ .../ResourceManager.ResourceLoader.cs.meta | 11 + .../Resource/ResourceManager.ResourceName.cs | 168 + .../ResourceManager.ResourceName.cs.meta | 11 + .../ResourceManager.ResourceNameComparer.cs | 35 + ...sourceManager.ResourceNameComparer.cs.meta | 11 + ...sourceManager.ResourceUpdater.ApplyInfo.cs | 169 + ...eManager.ResourceUpdater.ApplyInfo.cs.meta | 11 + ...ourceManager.ResourceUpdater.UpdateInfo.cs | 186 ++ ...Manager.ResourceUpdater.UpdateInfo.cs.meta | 11 + .../ResourceManager.ResourceUpdater.cs | 1016 ++++++ .../ResourceManager.ResourceUpdater.cs.meta | 11 + ...urceManager.ResourceVerifier.VerifyInfo.cs | 110 + ...anager.ResourceVerifier.VerifyInfo.cs.meta | 11 + .../ResourceManager.ResourceVerifier.cs | 389 +++ .../ResourceManager.ResourceVerifier.cs.meta | 11 + .../ResourceManager.VersionListProcessor.cs | 249 ++ ...sourceManager.VersionListProcessor.cs.meta | 11 + .../GameFramework/Resource/ResourceManager.cs | 2587 ++++++++++++++++ .../Resource/ResourceManager.cs.meta | 11 + .../GameFramework/Resource/ResourceMode.cs | 35 + .../Resource/ResourceMode.cs.meta | 11 + .../ResourcePackVersionList.Resource.cs | 160 + .../ResourcePackVersionList.Resource.cs.meta | 11 + .../Resource/ResourcePackVersionList.cs | 115 + .../Resource/ResourcePackVersionList.cs.meta | 11 + .../ResourcePackVersionListSerializer.cs | 33 + .../ResourcePackVersionListSerializer.cs.meta | 11 + .../ResourceUpdateAllCompleteEventArgs.cs | 38 + ...ResourceUpdateAllCompleteEventArgs.cs.meta | 11 + .../ResourceUpdateChangedEventArgs.cs | 104 + .../ResourceUpdateChangedEventArgs.cs.meta | 11 + .../ResourceUpdateFailureEventArgs.cs | 105 + .../ResourceUpdateFailureEventArgs.cs.meta | 11 + .../Resource/ResourceUpdateStartEventArgs.cs | 117 + .../ResourceUpdateStartEventArgs.cs.meta | 11 + .../ResourceUpdateSuccessEventArgs.cs | 104 + .../ResourceUpdateSuccessEventArgs.cs.meta | 11 + .../ResourceVerifyFailureEventArgs.cs | 52 + .../ResourceVerifyFailureEventArgs.cs.meta | 11 + .../Resource/ResourceVerifyStartEventArgs.cs | 65 + .../ResourceVerifyStartEventArgs.cs.meta | 11 + .../ResourceVerifySuccessEventArgs.cs | 65 + .../ResourceVerifySuccessEventArgs.cs.meta | 11 + .../Resource/UnloadSceneCallbacks.cs | 65 + .../Resource/UnloadSceneCallbacks.cs.meta | 11 + .../Resource/UnloadSceneFailureCallback.cs | 16 + .../UnloadSceneFailureCallback.cs.meta | 11 + .../Resource/UnloadSceneSuccessCallback.cs | 16 + .../UnloadSceneSuccessCallback.cs.meta | 11 + .../Resource/UpdatableVersionList.Asset.cs | 62 + .../UpdatableVersionList.Asset.cs.meta | 11 + .../UpdatableVersionList.FileSystem.cs | 62 + .../UpdatableVersionList.FileSystem.cs.meta | 11 + .../Resource/UpdatableVersionList.Resource.cs | 160 + .../UpdatableVersionList.Resource.cs.meta | 11 + .../UpdatableVersionList.ResourceGroup.cs | 62 + ...UpdatableVersionList.ResourceGroup.cs.meta | 11 + .../Resource/UpdatableVersionList.cs | 150 + .../Resource/UpdatableVersionList.cs.meta | 11 + .../UpdatableVersionListSerializer.cs | 33 + .../UpdatableVersionListSerializer.cs.meta | 11 + .../UpdateResourcesCompleteCallback.cs | 16 + .../UpdateResourcesCompleteCallback.cs.meta | 11 + .../Resource/UpdateVersionListCallbacks.cs | 65 + .../UpdateVersionListCallbacks.cs.meta | 11 + .../UpdateVersionListFailureCallback.cs | 16 + .../UpdateVersionListFailureCallback.cs.meta | 11 + .../UpdateVersionListSuccessCallback.cs | 16 + .../UpdateVersionListSuccessCallback.cs.meta | 11 + .../VerifyResourcesCompleteCallback.cs | 15 + .../VerifyResourcesCompleteCallback.cs.meta | 11 + .../Runtime/GameFramework/Scene.meta | 8 + .../GameFramework/Scene/ISceneManager.cs | 160 + .../GameFramework/Scene/ISceneManager.cs.meta | 11 + .../LoadSceneDependencyAssetEventArgs.cs | 104 + .../LoadSceneDependencyAssetEventArgs.cs.meta | 11 + .../Scene/LoadSceneFailureEventArgs.cs | 78 + .../Scene/LoadSceneFailureEventArgs.cs.meta | 11 + .../Scene/LoadSceneSuccessEventArgs.cs | 78 + .../Scene/LoadSceneSuccessEventArgs.cs.meta | 11 + .../Scene/LoadSceneUpdateEventArgs.cs | 78 + .../Scene/LoadSceneUpdateEventArgs.cs.meta | 11 + .../GameFramework/Scene/SceneManager.cs | 508 +++ .../GameFramework/Scene/SceneManager.cs.meta | 11 + .../Scene/UnloadSceneFailureEventArgs.cs | 65 + .../Scene/UnloadSceneFailureEventArgs.cs.meta | 11 + .../Scene/UnloadSceneSuccessEventArgs.cs | 65 + .../Scene/UnloadSceneSuccessEventArgs.cs.meta | 11 + .../Runtime/GameFramework/Setting.meta | 8 + .../GameFramework/Setting/ISettingHelper.cs | 206 ++ .../Setting/ISettingHelper.cs.meta | 11 + .../GameFramework/Setting/ISettingManager.cs | 212 ++ .../Setting/ISettingManager.cs.meta | 11 + .../GameFramework/Setting/SettingManager.cs | 565 ++++ .../Setting/SettingManager.cs.meta | 11 + .../Runtime/GameFramework/Sound.meta | 8 + .../Runtime/GameFramework/Sound/Constant.cs | 28 + .../GameFramework/Sound/Constant.cs.meta | 11 + .../GameFramework/Sound/ISoundAgent.cs | 210 ++ .../GameFramework/Sound/ISoundAgent.cs.meta | 11 + .../GameFramework/Sound/ISoundAgentHelper.cs | 164 + .../Sound/ISoundAgentHelper.cs.meta | 11 + .../GameFramework/Sound/ISoundGroup.cs | 77 + .../GameFramework/Sound/ISoundGroup.cs.meta | 11 + .../GameFramework/Sound/ISoundGroupHelper.cs | 16 + .../Sound/ISoundGroupHelper.cs.meta | 11 + .../GameFramework/Sound/ISoundHelper.cs | 21 + .../GameFramework/Sound/ISoundHelper.cs.meta | 11 + .../GameFramework/Sound/ISoundManager.cs | 263 ++ .../GameFramework/Sound/ISoundManager.cs.meta | 11 + .../PlaySoundDependencyAssetEventArgs.cs | 143 + .../PlaySoundDependencyAssetEventArgs.cs.meta | 11 + .../GameFramework/Sound/PlaySoundErrorCode.cs | 45 + .../Sound/PlaySoundErrorCode.cs.meta | 11 + .../Sound/PlaySoundFailureEventArgs.cs | 130 + .../Sound/PlaySoundFailureEventArgs.cs.meta | 11 + .../GameFramework/Sound/PlaySoundParams.cs | 249 ++ .../Sound/PlaySoundParams.cs.meta | 11 + .../Sound/PlaySoundSuccessEventArgs.cs | 104 + .../Sound/PlaySoundSuccessEventArgs.cs.meta | 11 + .../Sound/PlaySoundUpdateEventArgs.cs | 117 + .../Sound/PlaySoundUpdateEventArgs.cs.meta | 11 + .../Sound/ResetSoundAgentEventArgs.cs | 39 + .../Sound/ResetSoundAgentEventArgs.cs.meta | 11 + .../Sound/SoundManager.PlaySoundInfo.cs | 78 + .../Sound/SoundManager.PlaySoundInfo.cs.meta | 11 + .../Sound/SoundManager.SoundAgent.cs | 421 +++ .../Sound/SoundManager.SoundAgent.cs.meta | 11 + .../Sound/SoundManager.SoundGroup.cs | 303 ++ .../Sound/SoundManager.SoundGroup.cs.meta | 11 + .../GameFramework/Sound/SoundManager.cs | 754 +++++ .../GameFramework/Sound/SoundManager.cs.meta | 11 + .../Runtime/GameFramework/UI.meta | 8 + .../UI/CloseUIFormCompleteEventArgs.cs | 91 + .../UI/CloseUIFormCompleteEventArgs.cs.meta | 11 + .../Runtime/GameFramework/UI/IUIForm.cs | 132 + .../Runtime/GameFramework/UI/IUIForm.cs.meta | 11 + .../Runtime/GameFramework/UI/IUIFormHelper.cs | 38 + .../GameFramework/UI/IUIFormHelper.cs.meta | 11 + .../Runtime/GameFramework/UI/IUIGroup.cs | 121 + .../Runtime/GameFramework/UI/IUIGroup.cs.meta | 11 + .../GameFramework/UI/IUIGroupHelper.cs | 21 + .../GameFramework/UI/IUIGroupHelper.cs.meta | 11 + .../Runtime/GameFramework/UI/IUIManager.cs | 382 +++ .../GameFramework/UI/IUIManager.cs.meta | 11 + .../UI/OpenUIFormDependencyAssetEventArgs.cs | 143 + ...OpenUIFormDependencyAssetEventArgs.cs.meta | 11 + .../UI/OpenUIFormFailureEventArgs.cs | 117 + .../UI/OpenUIFormFailureEventArgs.cs.meta | 11 + .../UI/OpenUIFormSuccessEventArgs.cs | 78 + .../UI/OpenUIFormSuccessEventArgs.cs.meta | 11 + .../UI/OpenUIFormUpdateEventArgs.cs | 117 + .../UI/OpenUIFormUpdateEventArgs.cs.meta | 11 + .../UI/UIManager.OpenUIFormInfo.cs | 78 + .../UI/UIManager.OpenUIFormInfo.cs.meta | 11 + .../UI/UIManager.UIFormInstanceObject.cs | 60 + .../UI/UIManager.UIFormInstanceObject.cs.meta | 11 + .../UI/UIManager.UIGroup.UIFormInfo.cs | 85 + .../UI/UIManager.UIGroup.UIFormInfo.cs.meta | 11 + .../GameFramework/UI/UIManager.UIGroup.cs | 517 ++++ .../UI/UIManager.UIGroup.cs.meta | 11 + .../Runtime/GameFramework/UI/UIManager.cs | 1059 +++++++ .../GameFramework/UI/UIManager.cs.meta | 11 + .../Runtime/GameFramework/Utility.meta | 8 + .../GameFramework/Utility/Utility.Assembly.cs | 109 + .../Utility/Utility.Assembly.cs.meta | 11 + .../Utility.Compression.ICompressionHelper.cs | 59 + ...ity.Compression.ICompressionHelper.cs.meta | 11 + .../Utility/Utility.Compression.cs | 344 +++ .../Utility/Utility.Compression.cs.meta | 11 + .../Utility/Utility.Converter.cs | 848 +++++ .../Utility/Utility.Converter.cs.meta | 11 + .../Utility/Utility.Encryption.cs | 134 + .../Utility/Utility.Encryption.cs.meta | 11 + .../Utility/Utility.Json.IJsonHelper.cs | 46 + .../Utility/Utility.Json.IJsonHelper.cs.meta | 11 + .../GameFramework/Utility/Utility.Json.cs | 119 + .../Utility/Utility.Json.cs.meta | 11 + .../GameFramework/Utility/Utility.Marshal.cs | 240 ++ .../Utility/Utility.Marshal.cs.meta | 11 + .../GameFramework/Utility/Utility.Path.cs | 100 + .../Utility/Utility.Path.cs.meta | 11 + .../GameFramework/Utility/Utility.Random.cs | 79 + .../Utility/Utility.Random.cs.meta | 11 + .../Utility/Utility.Text.ITextHelper.cs | 405 +++ .../Utility/Utility.Text.ITextHelper.cs.meta | 11 + .../GameFramework/Utility/Utility.Text.cs | 621 ++++ .../Utility/Utility.Text.cs.meta | 11 + .../Utility/Utility.Verifier.Crc32.cs | 94 + .../Utility/Utility.Verifier.Crc32.cs.meta | 11 + .../GameFramework/Utility/Utility.Verifier.cs | 195 ++ .../Utility/Utility.Verifier.cs.meta | 11 + .../Runtime/GameFramework/Utility/Utility.cs | 16 + .../GameFramework/Utility/Utility.cs.meta | 11 + .../Runtime/GameFramework/WebRequest.meta | 8 + .../GameFramework/WebRequest/Constant.cs | 20 + .../GameFramework/WebRequest/Constant.cs.meta | 11 + .../WebRequest/IWebRequestAgentHelper.cs | 47 + .../WebRequest/IWebRequestAgentHelper.cs.meta | 11 + .../WebRequest/IWebRequestManager.cs | 277 ++ .../WebRequest/IWebRequestManager.cs.meta | 11 + .../WebRequestAgentHelperCompleteEventArgs.cs | 54 + ...equestAgentHelperCompleteEventArgs.cs.meta | 11 + .../WebRequestAgentHelperErrorEventArgs.cs | 52 + ...ebRequestAgentHelperErrorEventArgs.cs.meta | 11 + .../WebRequest/WebRequestFailureEventArgs.cs | 91 + .../WebRequestFailureEventArgs.cs.meta | 11 + .../WebRequestManager.WebRequestAgent.cs | 176 ++ .../WebRequestManager.WebRequestAgent.cs.meta | 11 + .../WebRequestManager.WebRequestTask.cs | 121 + .../WebRequestManager.WebRequestTask.cs.meta | 11 + .../WebRequestManager.WebRequestTaskStatus.cs | 38 + ...equestManager.WebRequestTaskStatus.cs.meta | 11 + .../WebRequest/WebRequestManager.cs | 483 +++ .../WebRequest/WebRequestManager.cs.meta | 11 + .../WebRequest/WebRequestStartEventArgs.cs | 78 + .../WebRequestStartEventArgs.cs.meta | 11 + .../WebRequest/WebRequestSuccessEventArgs.cs | 93 + .../WebRequestSuccessEventArgs.cs.meta | 11 + .../Runtime/UnityGameFramework.meta | 8 + .../Runtime/UnityGameFramework/Base.meta | 8 + .../UnityGameFramework/Base/BaseComponent.cs | 425 +++ .../Base/BaseComponent.cs.meta | 11 + .../UnityGameFramework/Base/GameEntry.cs | 150 + .../UnityGameFramework/Base/GameEntry.cs.meta | 11 + .../Base/GameFrameworkComponent.cs | 25 + .../Base/GameFrameworkComponent.cs.meta | 11 + .../UnityGameFramework/Base/ShutdownType.cs | 30 + .../Base/ShutdownType.cs.meta | 11 + .../Runtime/UnityGameFramework/Config.meta | 8 + .../Config/ConfigComponent.cs | 408 +++ .../Config/ConfigComponent.cs.meta | 11 + .../Config/ConfigHelperBase.cs | 68 + .../Config/ConfigHelperBase.cs.meta | 11 + .../Config/DefaultConfigHelper.cs | 181 ++ .../Config/DefaultConfigHelper.cs.meta | 11 + .../LoadConfigDependencyAssetEventArgs.cs | 119 + ...LoadConfigDependencyAssetEventArgs.cs.meta | 11 + .../Config/LoadConfigFailureEventArgs.cs | 95 + .../Config/LoadConfigFailureEventArgs.cs.meta | 11 + .../Config/LoadConfigSuccessEventArgs.cs | 95 + .../Config/LoadConfigSuccessEventArgs.cs.meta | 11 + .../Config/LoadConfigUpdateEventArgs.cs | 95 + .../Config/LoadConfigUpdateEventArgs.cs.meta | 11 + .../Runtime/UnityGameFramework/DataNode.meta | 8 + .../DataNode/DataNodeComponent.cs | 210 ++ .../DataNode/DataNodeComponent.cs.meta | 11 + .../Runtime/UnityGameFramework/DataTable.meta | 8 + .../DataTable/DataRowBase.cs | 51 + .../DataTable/DataRowBase.cs.meta | 11 + .../DataTable/DataTableComponent.cs | 399 +++ .../DataTable/DataTableComponent.cs.meta | 11 + .../DataTable/DataTableHelperBase.cs | 68 + .../DataTable/DataTableHelperBase.cs.meta | 11 + .../DataTable/DefaultDataTableHelper.cs | 171 ++ .../DataTable/DefaultDataTableHelper.cs.meta | 11 + .../LoadDataTableDependencyAssetEventArgs.cs | 119 + ...dDataTableDependencyAssetEventArgs.cs.meta | 11 + .../LoadDataTableFailureEventArgs.cs | 95 + .../LoadDataTableFailureEventArgs.cs.meta | 11 + .../LoadDataTableSuccessEventArgs.cs | 95 + .../LoadDataTableSuccessEventArgs.cs.meta | 11 + .../DataTable/LoadDataTableUpdateEventArgs.cs | 95 + .../LoadDataTableUpdateEventArgs.cs.meta | 11 + .../Runtime/UnityGameFramework/Debugger.meta | 8 + .../Debugger/DebuggerActiveWindowType.cs | 35 + .../Debugger/DebuggerActiveWindowType.cs.meta | 11 + .../DebuggerComponent.ConsoleWindow.cs | 509 +++ .../DebuggerComponent.ConsoleWindow.cs.meta | 11 + ...rComponent.EnvironmentInformationWindow.cs | 96 + ...onent.EnvironmentInformationWindow.cs.meta | 11 + .../Debugger/DebuggerComponent.FpsCounter.cs | 83 + .../DebuggerComponent.FpsCounter.cs.meta | 11 + ...ggerComponent.GraphicsInformationWindow.cs | 170 + ...omponent.GraphicsInformationWindow.cs.meta | 11 + ...nent.InputAccelerationInformationWindow.cs | 46 + ...InputAccelerationInformationWindow.cs.meta | 11 + ...Component.InputCompassInformationWindow.cs | 48 + ...nent.InputCompassInformationWindow.cs.meta | 11 + ...mponent.InputGyroscopeInformationWindow.cs | 49 + ...nt.InputGyroscopeInformationWindow.cs.meta | 11 + ...omponent.InputLocationInformationWindow.cs | 50 + ...ent.InputLocationInformationWindow.cs.meta | 11 + ...Component.InputSummaryInformationWindow.cs | 39 + ...nent.InputSummaryInformationWindow.cs.meta | 11 + ...erComponent.InputTouchInformationWindow.cs | 50 + ...ponent.InputTouchInformationWindow.cs.meta | 11 + .../Debugger/DebuggerComponent.LogNode.cs | 125 + .../DebuggerComponent.LogNode.cs.meta | 11 + ...uggerComponent.NetworkInformationWindow.cs | 70 + ...Component.NetworkInformationWindow.cs.meta | 11 + ...erComponent.ObjectPoolInformationWindow.cs | 95 + ...ponent.ObjectPoolInformationWindow.cs.meta | 11 + .../DebuggerComponent.OperationsWindow.cs | 66 + ...DebuggerComponent.OperationsWindow.cs.meta | 11 + ...DebuggerComponent.PathInformationWindow.cs | 36 + ...gerComponent.PathInformationWindow.cs.meta | 11 + ...ggerComponent.ProfilerInformationWindow.cs | 67 + ...omponent.ProfilerInformationWindow.cs.meta | 11 + ...uggerComponent.QualityInformationWindow.cs | 110 + ...Component.QualityInformationWindow.cs.meta | 11 + ...omponent.ReferencePoolInformationWindow.cs | 114 + ...ent.ReferencePoolInformationWindow.cs.meta | 11 + ...t.RuntimeMemoryInformationWindow.Sample.cs | 67 + ...timeMemoryInformationWindow.Sample.cs.meta | 11 + ...omponent.RuntimeMemoryInformationWindow.cs | 142 + ...ent.RuntimeMemoryInformationWindow.cs.meta | 11 + ...onent.RuntimeMemorySummaryWindow.Record.cs | 61 + ....RuntimeMemorySummaryWindow.Record.cs.meta | 11 + ...gerComponent.RuntimeMemorySummaryWindow.cs | 130 + ...mponent.RuntimeMemorySummaryWindow.cs.meta | 11 + ...ebuggerComponent.SceneInformationWindow.cs | 44 + ...erComponent.SceneInformationWindow.cs.meta | 11 + ...buggerComponent.ScreenInformationWindow.cs | 95 + ...rComponent.ScreenInformationWindow.cs.meta | 11 + ...rComponent.ScrollableDebuggerWindowBase.cs | 101 + ...onent.ScrollableDebuggerWindowBase.cs.meta | 11 + .../DebuggerComponent.SettingsWindow.cs | 219 ++ .../DebuggerComponent.SettingsWindow.cs.meta | 11 + ...buggerComponent.SystemInformationWindow.cs | 62 + ...rComponent.SystemInformationWindow.cs.meta | 11 + ...DebuggerComponent.TimeInformationWindow.cs | 76 + ...gerComponent.TimeInformationWindow.cs.meta | 11 + ...gerComponent.WebPlayerInformationWindow.cs | 40 + ...mponent.WebPlayerInformationWindow.cs.meta | 11 + .../Debugger/DebuggerComponent.cs | 437 +++ .../Debugger/DebuggerComponent.cs.meta | 11 + .../Runtime/UnityGameFramework/Download.meta | 8 + .../Download/DownloadAgentHelperBase.cs | 73 + .../Download/DownloadAgentHelperBase.cs.meta | 11 + .../Download/DownloadComponent.cs | 409 +++ .../Download/DownloadComponent.cs.meta | 11 + .../Download/DownloadFailureEventArgs.cs | 119 + .../Download/DownloadFailureEventArgs.cs.meta | 11 + .../Download/DownloadStartEventArgs.cs | 119 + .../Download/DownloadStartEventArgs.cs.meta | 11 + .../Download/DownloadSuccessEventArgs.cs | 119 + .../Download/DownloadSuccessEventArgs.cs.meta | 11 + .../Download/DownloadUpdateEventArgs.cs | 119 + .../Download/DownloadUpdateEventArgs.cs.meta | 11 + ...uestDownloadAgentHelper.DownloadHandler.cs | 48 + ...ownloadAgentHelper.DownloadHandler.cs.meta | 11 + .../UnityWebRequestDownloadAgentHelper.cs | 248 ++ ...UnityWebRequestDownloadAgentHelper.cs.meta | 11 + .../Download/WWWDownloadAgentHelper.cs | 246 ++ .../Download/WWWDownloadAgentHelper.cs.meta | 11 + .../Runtime/UnityGameFramework/Entity.meta | 8 + .../Entity/AttachEntityInfo.cs | 54 + .../Entity/AttachEntityInfo.cs.meta | 11 + .../Entity/DefaultEntityGroupHelper.cs | 16 + .../Entity/DefaultEntityGroupHelper.cs.meta | 11 + .../Entity/DefaultEntityHelper.cs | 73 + .../Entity/DefaultEntityHelper.cs.meta | 11 + .../UnityGameFramework/Entity/Entity.cs | 280 ++ .../UnityGameFramework/Entity/Entity.cs.meta | 11 + .../Entity/EntityComponent.EntityGroup.cs | 74 + .../EntityComponent.EntityGroup.cs.meta | 11 + .../Entity/EntityComponent.cs | 1146 +++++++ .../Entity/EntityComponent.cs.meta | 11 + .../Entity/EntityGroupHelperBase.cs | 19 + .../Entity/EntityGroupHelperBase.cs.meta | 11 + .../Entity/EntityHelperBase.cs | 41 + .../Entity/EntityHelperBase.cs.meta | 11 + .../UnityGameFramework/Entity/EntityLogic.cs | 202 ++ .../Entity/EntityLogic.cs.meta | 11 + .../Entity/HideEntityCompleteEventArgs.cs | 108 + .../HideEntityCompleteEventArgs.cs.meta | 11 + .../ShowEntityDependencyAssetEventArgs.cs | 157 + ...ShowEntityDependencyAssetEventArgs.cs.meta | 11 + .../Entity/ShowEntityFailureEventArgs.cs | 134 + .../Entity/ShowEntityFailureEventArgs.cs.meta | 11 + .../Entity/ShowEntityInfo.cs | 54 + .../Entity/ShowEntityInfo.cs.meta | 11 + .../Entity/ShowEntitySuccessEventArgs.cs | 110 + .../Entity/ShowEntitySuccessEventArgs.cs.meta | 11 + .../Entity/ShowEntityUpdateEventArgs.cs | 133 + .../Entity/ShowEntityUpdateEventArgs.cs.meta | 11 + .../Runtime/UnityGameFramework/Event.meta | 8 + .../Event/EventComponent.cs | 135 + .../Event/EventComponent.cs.meta | 11 + .../UnityGameFramework/FileSystem.meta | 8 + .../FileSystem/AndroidFileSystemStream.cs | 293 ++ .../AndroidFileSystemStream.cs.meta | 11 + .../FileSystem/DefaultFileSystemHelper.cs | 39 + .../DefaultFileSystemHelper.cs.meta | 11 + .../FileSystem/FileSystemComponent.cs | 146 + .../FileSystem/FileSystemComponent.cs.meta | 11 + .../FileSystem/FileSystemHelperBase.cs | 27 + .../FileSystem/FileSystemHelperBase.cs.meta | 11 + .../Runtime/UnityGameFramework/Fsm.meta | 8 + .../UnityGameFramework/Fsm/FsmComponent.cs | 269 ++ .../Fsm/FsmComponent.cs.meta | 11 + .../UnityGameFramework/GameFramework.prefab | 1190 +++++++ .../GameFramework.prefab.meta | 7 + .../UnityGameFramework/Localization.meta | 8 + .../Localization/DefaultLocalizationHelper.cs | 238 ++ .../DefaultLocalizationHelper.cs.meta | 11 + .../LoadDictionaryDependencyAssetEventArgs.cs | 119 + ...DictionaryDependencyAssetEventArgs.cs.meta | 11 + .../LoadDictionaryFailureEventArgs.cs | 95 + .../LoadDictionaryFailureEventArgs.cs.meta | 11 + .../LoadDictionarySuccessEventArgs.cs | 95 + .../LoadDictionarySuccessEventArgs.cs.meta | 11 + .../LoadDictionaryUpdateEventArgs.cs | 95 + .../LoadDictionaryUpdateEventArgs.cs.meta | 11 + .../Localization/LocalizationComponent.cs | 789 +++++ .../LocalizationComponent.cs.meta | 11 + .../Localization/LocalizationHelperBase.cs | 76 + .../LocalizationHelperBase.cs.meta | 11 + .../Runtime/UnityGameFramework/Network.meta | 8 + .../Network/NetworkClosedEventArgs.cs | 72 + .../Network/NetworkClosedEventArgs.cs.meta | 11 + .../Network/NetworkComponent.cs | 152 + .../Network/NetworkComponent.cs.meta | 11 + .../Network/NetworkConnectedEventArgs.cs | 84 + .../Network/NetworkConnectedEventArgs.cs.meta | 11 + .../Network/NetworkCustomErrorEventArgs.cs | 84 + .../NetworkCustomErrorEventArgs.cs.meta | 11 + .../Network/NetworkErrorEventArgs.cs | 107 + .../Network/NetworkErrorEventArgs.cs.meta | 11 + .../Network/NetworkMissHeartBeatEventArgs.cs | 84 + .../NetworkMissHeartBeatEventArgs.cs.meta | 11 + .../UnityGameFramework/ObjectPool.meta | 8 + .../ObjectPool/ObjectPoolComponent.cs | 1033 +++++++ .../ObjectPool/ObjectPoolComponent.cs.meta | 11 + .../Runtime/UnityGameFramework/Procedure.meta | 8 + .../Procedure/ProcedureComponent.cs | 162 + .../Procedure/ProcedureComponent.cs.meta | 11 + .../UnityGameFramework/ReferencePool.meta | 8 + .../ReferencePool/ReferencePoolComponent.cs | 72 + .../ReferencePoolComponent.cs.meta | 11 + .../ReferencePool/ReferenceStrictCheckType.cs | 35 + .../ReferenceStrictCheckType.cs.meta | 11 + .../Runtime/UnityGameFramework/Resource.meta | 8 + ...zer.LocalVersionListDeserializeCallback.cs | 114 + ...ocalVersionListDeserializeCallback.cs.meta | 11 + ...lizer.LocalVersionListSerializeCallback.cs | 135 + ....LocalVersionListSerializeCallback.cs.meta | 11 + ...r.PackageVersionListDeserializeCallback.cs | 264 ++ ...kageVersionListDeserializeCallback.cs.meta | 11 + ...zer.PackageVersionListSerializeCallback.cs | 239 ++ ...ackageVersionListSerializeCallback.cs.meta | 11 + ...ourcePackVersionListDeserializeCallback.cs | 52 + ...PackVersionListDeserializeCallback.cs.meta | 11 + ...esourcePackVersionListSerializeCallback.cs | 65 + ...cePackVersionListSerializeCallback.cs.meta | 11 + ...UpdatableVersionListDeserializeCallback.cs | 270 ++ ...ableVersionListDeserializeCallback.cs.meta | 11 + ...r.UpdatableVersionListSerializeCallback.cs | 245 ++ ...atableVersionListSerializeCallback.cs.meta | 11 + ...UpdatableVersionListTryGetValueCallback.cs | 70 + ...ableVersionListTryGetValueCallback.cs.meta | 11 + .../Resource/BuiltinVersionListSerializer.cs | 54 + .../BuiltinVersionListSerializer.cs.meta | 11 + .../DefaultLoadResourceAgentHelper.cs | 595 ++++ .../DefaultLoadResourceAgentHelper.cs.meta | 11 + .../Resource/DefaultResourceHelper.cs | 185 ++ .../Resource/DefaultResourceHelper.cs.meta | 11 + .../Resource/EditorResourceComponent.cs | 1867 +++++++++++ .../Resource/EditorResourceComponent.cs.meta | 11 + .../Resource/LoadResourceAgentHelperBase.cs | 96 + .../LoadResourceAgentHelperBase.cs.meta | 11 + .../Resource/ReadWritePathType.cs | 30 + .../Resource/ReadWritePathType.cs.meta | 11 + .../Resource/ResourceApplyFailureEventArgs.cs | 95 + .../ResourceApplyFailureEventArgs.cs.meta | 11 + .../Resource/ResourceApplyStartEventArgs.cs | 95 + .../ResourceApplyStartEventArgs.cs.meta | 11 + .../Resource/ResourceApplySuccessEventArgs.cs | 119 + .../ResourceApplySuccessEventArgs.cs.meta | 11 + .../Resource/ResourceComponent.cs | 1525 +++++++++ .../Resource/ResourceComponent.cs.meta | 11 + .../Resource/ResourceHelperBase.cs | 40 + .../Resource/ResourceHelperBase.cs.meta | 11 + .../ResourceUpdateAllCompleteEventArgs.cs | 58 + ...ResourceUpdateAllCompleteEventArgs.cs.meta | 11 + .../ResourceUpdateChangedEventArgs.cs | 119 + .../ResourceUpdateChangedEventArgs.cs.meta | 11 + .../ResourceUpdateFailureEventArgs.cs | 119 + .../ResourceUpdateFailureEventArgs.cs.meta | 11 + .../Resource/ResourceUpdateStartEventArgs.cs | 131 + .../ResourceUpdateStartEventArgs.cs.meta | 11 + .../ResourceUpdateSuccessEventArgs.cs | 119 + .../ResourceUpdateSuccessEventArgs.cs.meta | 11 + .../ResourceVerifyFailureEventArgs.cs | 71 + .../ResourceVerifyFailureEventArgs.cs.meta | 11 + .../Resource/ResourceVerifyStartEventArgs.cs | 83 + .../ResourceVerifyStartEventArgs.cs.meta | 11 + .../ResourceVerifySuccessEventArgs.cs | 83 + .../ResourceVerifySuccessEventArgs.cs.meta | 11 + .../UnityGameFramework/Resource/SceneAsset.cs | 13 + .../Resource/SceneAsset.cs.meta | 11 + .../Runtime/UnityGameFramework/Scene.meta | 8 + .../Scene/ActiveSceneChangedEventArgs.cs | 85 + .../Scene/ActiveSceneChangedEventArgs.cs.meta | 11 + .../LoadSceneDependencyAssetEventArgs.cs | 119 + .../LoadSceneDependencyAssetEventArgs.cs.meta | 11 + .../Scene/LoadSceneFailureEventArgs.cs | 95 + .../Scene/LoadSceneFailureEventArgs.cs.meta | 11 + .../Scene/LoadSceneSuccessEventArgs.cs | 95 + .../Scene/LoadSceneSuccessEventArgs.cs.meta | 11 + .../Scene/LoadSceneUpdateEventArgs.cs | 95 + .../Scene/LoadSceneUpdateEventArgs.cs.meta | 11 + .../Scene/SceneComponent.cs | 477 +++ .../Scene/SceneComponent.cs.meta | 11 + .../Scene/UnloadSceneFailureEventArgs.cs | 83 + .../Scene/UnloadSceneFailureEventArgs.cs.meta | 11 + .../Scene/UnloadSceneSuccessEventArgs.cs | 83 + .../Scene/UnloadSceneSuccessEventArgs.cs.meta | 11 + .../Runtime/UnityGameFramework/Setting.meta | 8 + .../Setting/DefaultSetting.cs | 313 ++ .../Setting/DefaultSetting.cs.meta | 11 + .../Setting/DefaultSettingHelper.cs | 387 +++ .../Setting/DefaultSettingHelper.cs.meta | 11 + .../Setting/DefaultSettingSerializer.cs | 35 + .../Setting/DefaultSettingSerializer.cs.meta | 11 + .../Setting/PlayerPrefsSettingHelper.cs | 312 ++ .../Setting/PlayerPrefsSettingHelper.cs.meta | 11 + .../Setting/SettingComponent.cs | 323 ++ .../Setting/SettingComponent.cs.meta | 11 + .../Setting/SettingHelperBase.cs | 208 ++ .../Setting/SettingHelperBase.cs.meta | 11 + .../Runtime/UnityGameFramework/Sound.meta | 8 + .../Sound/DefaultSoundAgentHelper.cs | 434 +++ .../Sound/DefaultSoundAgentHelper.cs.meta | 11 + .../Sound/DefaultSoundGroupHelper.cs | 16 + .../Sound/DefaultSoundGroupHelper.cs.meta | 11 + .../Sound/DefaultSoundHelper.cs | 36 + .../Sound/DefaultSoundHelper.cs.meta | 11 + .../PlaySoundDependencyAssetEventArgs.cs | 169 + .../PlaySoundDependencyAssetEventArgs.cs.meta | 11 + .../Sound/PlaySoundFailureEventArgs.cs | 158 + .../Sound/PlaySoundFailureEventArgs.cs.meta | 11 + .../UnityGameFramework/Sound/PlaySoundInfo.cs | 66 + .../Sound/PlaySoundInfo.cs.meta | 11 + .../Sound/PlaySoundSuccessEventArgs.cs | 134 + .../Sound/PlaySoundSuccessEventArgs.cs.meta | 11 + .../Sound/PlaySoundUpdateEventArgs.cs | 145 + .../Sound/PlaySoundUpdateEventArgs.cs.meta | 11 + .../Sound/SoundAgentHelperBase.cs | 188 ++ .../Sound/SoundAgentHelperBase.cs.meta | 11 + .../Sound/SoundComponent.SoundGroup.cs | 74 + .../Sound/SoundComponent.SoundGroup.cs.meta | 11 + .../Sound/SoundComponent.cs | 692 +++++ .../Sound/SoundComponent.cs.meta | 11 + .../Sound/SoundGroupHelperBase.cs | 37 + .../Sound/SoundGroupHelperBase.cs.meta | 11 + .../Sound/SoundHelperBase.cs | 24 + .../Sound/SoundHelperBase.cs.meta | 11 + .../Runtime/UnityGameFramework/UI.meta | 8 + .../UI/CloseUIFormCompleteEventArgs.cs | 108 + .../UI/CloseUIFormCompleteEventArgs.cs.meta | 11 + .../UI/DefaultUIFormHelper.cs | 74 + .../UI/DefaultUIFormHelper.cs.meta | 11 + .../UI/DefaultUIGroupHelper.cs | 59 + .../UI/DefaultUIGroupHelper.cs.meta | 11 + .../UI/OpenUIFormDependencyAssetEventArgs.cs | 155 + ...OpenUIFormDependencyAssetEventArgs.cs.meta | 11 + .../UI/OpenUIFormFailureEventArgs.cs | 131 + .../UI/OpenUIFormFailureEventArgs.cs.meta | 11 + .../UI/OpenUIFormSuccessEventArgs.cs | 96 + .../UI/OpenUIFormSuccessEventArgs.cs.meta | 11 + .../UI/OpenUIFormUpdateEventArgs.cs | 131 + .../UI/OpenUIFormUpdateEventArgs.cs.meta | 11 + .../UI/UIComponent.UIGroup.cs | 41 + .../UI/UIComponent.UIGroup.cs.meta | 11 + .../UnityGameFramework/UI/UIComponent.cs | 732 +++++ .../UnityGameFramework/UI/UIComponent.cs.meta | 11 + .../Runtime/UnityGameFramework/UI/UIForm.cs | 305 ++ .../UnityGameFramework/UI/UIForm.cs.meta | 11 + .../UnityGameFramework/UI/UIFormHelperBase.cs | 41 + .../UI/UIFormHelperBase.cs.meta | 11 + .../UnityGameFramework/UI/UIFormLogic.cs | 207 ++ .../UnityGameFramework/UI/UIFormLogic.cs.meta | 11 + .../UI/UIGroupHelperBase.cs | 24 + .../UI/UIGroupHelperBase.cs.meta | 11 + .../Runtime/UnityGameFramework/UI/UIIntKey.cs | 35 + .../UnityGameFramework/UI/UIIntKey.cs.meta | 11 + .../UnityGameFramework/UI/UIStringKey.cs | 35 + .../UnityGameFramework/UI/UIStringKey.cs.meta | 11 + .../UnityGameFramework.asmdef | 16 + .../UnityGameFramework.asmdef.meta | 7 + .../Runtime/UnityGameFramework/Utility.meta | 8 + .../Utility/BinaryExtension.cs | 197 ++ .../Utility/BinaryExtension.cs.meta | 11 + .../Utility/DefaultCompressionHelper.cs | 212 ++ .../Utility/DefaultCompressionHelper.cs.meta | 11 + .../Utility/DefaultJsonHelper.cs | 56 + .../Utility/DefaultJsonHelper.cs.meta | 11 + .../Utility/DefaultLogHelper.cs | 48 + .../Utility/DefaultLogHelper.cs.meta | 11 + .../Utility/DefaultTextHelper.cs | 592 ++++ .../Utility/DefaultTextHelper.cs.meta | 11 + .../Utility/DefaultVersionHelper.cs | 40 + .../Utility/DefaultVersionHelper.cs.meta | 11 + .../UnityGameFramework/Utility/Helper.cs | 75 + .../UnityGameFramework/Utility/Helper.cs.meta | 11 + .../Runtime/UnityGameFramework/Utility/Log.cs | 2728 +++++++++++++++++ .../UnityGameFramework/Utility/Log.cs.meta | 11 + .../Utility/StringExtension.cs | 66 + .../Utility/StringExtension.cs.meta | 11 + .../Utility/UnityExtension.cs | 347 +++ .../Utility/UnityExtension.cs.meta | 11 + .../Runtime/UnityGameFramework/Variable.meta | 8 + .../UnityGameFramework/Variable/VarBoolean.cs | 44 + .../Variable/VarBoolean.cs.meta | 11 + .../UnityGameFramework/Variable/VarByte.cs | 45 + .../Variable/VarByte.cs.meta | 11 + .../Variable/VarByteArray.cs | 44 + .../Variable/VarByteArray.cs.meta | 11 + .../UnityGameFramework/Variable/VarChar.cs | 44 + .../Variable/VarChar.cs.meta | 11 + .../Variable/VarCharArray.cs | 44 + .../Variable/VarCharArray.cs.meta | 11 + .../UnityGameFramework/Variable/VarColor.cs | 45 + .../Variable/VarColor.cs.meta | 11 + .../UnityGameFramework/Variable/VarColor32.cs | 45 + .../Variable/VarColor32.cs.meta | 11 + .../Variable/VarDateTime.cs | 45 + .../Variable/VarDateTime.cs.meta | 11 + .../UnityGameFramework/Variable/VarDecimal.cs | 44 + .../Variable/VarDecimal.cs.meta | 11 + .../UnityGameFramework/Variable/VarDouble.cs | 44 + .../Variable/VarDouble.cs.meta | 11 + .../Variable/VarGameObject.cs | 45 + .../Variable/VarGameObject.cs.meta | 11 + .../UnityGameFramework/Variable/VarInt16.cs | 44 + .../Variable/VarInt16.cs.meta | 11 + .../UnityGameFramework/Variable/VarInt32.cs | 44 + .../Variable/VarInt32.cs.meta | 11 + .../UnityGameFramework/Variable/VarInt64.cs | 44 + .../Variable/VarInt64.cs.meta | 11 + .../Variable/VarMaterial.cs | 45 + .../Variable/VarMaterial.cs.meta | 11 + .../UnityGameFramework/Variable/VarObject.cs | 24 + .../Variable/VarObject.cs.meta | 11 + .../Variable/VarQuaternion.cs | 45 + .../Variable/VarQuaternion.cs.meta | 11 + .../UnityGameFramework/Variable/VarRect.cs | 45 + .../Variable/VarRect.cs.meta | 11 + .../UnityGameFramework/Variable/VarSByte.cs | 44 + .../Variable/VarSByte.cs.meta | 11 + .../UnityGameFramework/Variable/VarSingle.cs | 44 + .../Variable/VarSingle.cs.meta | 11 + .../UnityGameFramework/Variable/VarString.cs | 44 + .../Variable/VarString.cs.meta | 11 + .../UnityGameFramework/Variable/VarTexture.cs | 45 + .../Variable/VarTexture.cs.meta | 11 + .../Variable/VarTransform.cs | 45 + .../Variable/VarTransform.cs.meta | 11 + .../UnityGameFramework/Variable/VarUInt16.cs | 44 + .../Variable/VarUInt16.cs.meta | 11 + .../UnityGameFramework/Variable/VarUInt32.cs | 44 + .../Variable/VarUInt32.cs.meta | 11 + .../UnityGameFramework/Variable/VarUInt64.cs | 44 + .../Variable/VarUInt64.cs.meta | 11 + .../Variable/VarUnityObject.cs | 45 + .../Variable/VarUnityObject.cs.meta | 11 + .../UnityGameFramework/Variable/VarVector2.cs | 45 + .../Variable/VarVector2.cs.meta | 11 + .../UnityGameFramework/Variable/VarVector3.cs | 45 + .../Variable/VarVector3.cs.meta | 11 + .../UnityGameFramework/Variable/VarVector4.cs | 45 + .../Variable/VarVector4.cs.meta | 11 + .../UnityGameFramework/WebRequest.meta | 8 + .../WebRequest/UnityWebRequestAgentHelper.cs | 186 ++ .../UnityWebRequestAgentHelper.cs.meta | 11 + .../WebRequest/WWWFormInfo.cs | 54 + .../WebRequest/WWWFormInfo.cs.meta | 11 + .../WebRequest/WWWWebRequestAgentHelper.cs | 166 + .../WWWWebRequestAgentHelper.cs.meta | 11 + .../WebRequest/WebRequestAgentHelperBase.cs | 49 + .../WebRequestAgentHelperBase.cs.meta | 11 + .../WebRequest/WebRequestComponent.cs | 564 ++++ .../WebRequest/WebRequestComponent.cs.meta | 11 + .../WebRequest/WebRequestFailureEventArgs.cs | 109 + .../WebRequestFailureEventArgs.cs.meta | 11 + .../WebRequest/WebRequestStartEventArgs.cs | 96 + .../WebRequestStartEventArgs.cs.meta | 11 + .../WebRequest/WebRequestSuccessEventArgs.cs | 111 + .../WebRequestSuccessEventArgs.cs.meta | 11 + .../package.json | 6 + .../package.json.meta | 7 + Packages/manifest.json | 39 + Packages/packages-lock.json | 377 +++ ProjectSettings/AudioManager.asset | 19 + ProjectSettings/ClusterInputManager.asset | 6 + ProjectSettings/DynamicsManager.asset | 34 + ProjectSettings/EditorBuildSettings.asset | 8 + ProjectSettings/EditorSettings.asset | 30 + ProjectSettings/GraphicsSettings.asset | 63 + ProjectSettings/InputManager.asset | 295 ++ ProjectSettings/MemorySettings.asset | 35 + ProjectSettings/NavMeshAreas.asset | 91 + ProjectSettings/PackageManagerSettings.asset | 35 + .../Settings.json | 5 + ProjectSettings/Physics2DSettings.asset | 56 + ProjectSettings/PresetManager.asset | 7 + ProjectSettings/ProjectSettings.asset | 865 ++++++ ProjectSettings/ProjectVersion.txt | 2 + ProjectSettings/QualitySettings.asset | 234 ++ ProjectSettings/TagManager.asset | 43 + ProjectSettings/TimeManager.asset | 9 + ProjectSettings/UnityConnectSettings.asset | 36 + ProjectSettings/VFXManager.asset | 12 + ProjectSettings/VersionControlSettings.asset | 8 + ProjectSettings/XRSettings.asset | 10 + 1341 files changed, 117897 insertions(+) create mode 100644 .gitignore create mode 100644 Packages/com.bywaystudios.gameframework/Editor.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/BaseComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/BaseComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ConfigComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ConfigComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/DataNodeComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/DataNodeComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/DataTableComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/DataTableComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/DebuggerComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/DebuggerComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/DownloadComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/DownloadComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/EditorResourceComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/EditorResourceComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/EntityComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/EntityComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/EventComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/EventComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/FileSystemComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/FileSystemComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/FsmComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/FsmComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/GameFrameworkInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/GameFrameworkInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/LocalizationComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/LocalizationComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/NetworkComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/NetworkComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ObjectPoolComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ObjectPoolComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ProcedureComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ProcedureComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ReferencePoolComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ReferencePoolComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ResourceComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/ResourceComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/SceneComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/SceneComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/SettingComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/SettingComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/SoundComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/SoundComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/UIComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/UIComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/WebRequestComponentInspector.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Inspector/WebRequestComponentInspector.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettings.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettings.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettingsConfigPathAttribute.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettingsConfigPathAttribute.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/ConfigPathAttribute.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/ConfigPathAttribute.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/Help.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/Help.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/HelperInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/HelperInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/LogRedirection.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/LogRedirection.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/LogScriptingDefineSymbols.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/LogScriptingDefineSymbols.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/OpenFolder.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/OpenFolder.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/ScriptingDefineSymbols.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/ScriptingDefineSymbols.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/Type.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/Misc/Type.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/AssetsOrder.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/AssetsOrder.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/DependencyData.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/DependencyData.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.CircularDependencyChecker.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.CircularDependencyChecker.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.Stamp.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.Stamp.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ScatteredAssetsOrder.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ScatteredAssetsOrder.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/AssetBundleCompressionType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/AssetBundleCompressionType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/IBuildEventHandler.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/IBuildEventHandler.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/Platform.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/Platform.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilder.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilder.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderConfigPathAttribute.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderConfigPathAttribute.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.AssetData.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.AssetData.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.BuildReport.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.BuildReport.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.FileSystemHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.FileSystemHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceCode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceCode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceData.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceData.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.VersionListData.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.VersionListData.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Asset.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Asset.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/AssetType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/AssetType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/LoadType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/LoadType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Resource.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Resource.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollection.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollection.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollectionConfigPathAttribute.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollectionConfigPathAttribute.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/AssetSorterType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/AssetSorterType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.MenuState.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.MenuState.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceFolder.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceFolder.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceItem.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceItem.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorConfigPathAttribute.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorConfigPathAttribute.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorController.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorController.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceAsset.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceAsset.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceFolder.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceFolder.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilder.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilder.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilderController.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilderController.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncTools.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncTools.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncToolsController.cs create mode 100644 Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncToolsController.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Editor/UnityGameFrameworkEditor.asmdef create mode 100644 Packages/com.bywaystudios.gameframework/Editor/UnityGameFrameworkEditor.asmdef.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProvider.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProvider.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProviderCreator.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProviderCreator.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProvider.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProvider.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProviderHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProviderHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct/TypeNamePair.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct/TypeNamePair.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/BaseEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/BaseEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.Event.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.Event.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPoolMode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPoolMode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkAction.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkAction.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEntry.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEntry.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkException.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkException.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkFunc.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkFunc.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedList.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedList.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedListRange.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedListRange.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkModule.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkModule.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkMultiDictionary.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkMultiDictionary.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkSerializer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkSerializer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.ILogHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.ILogHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLogLevel.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLogLevel.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/IReference.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/IReference.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePoolInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePoolInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/ITaskAgent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/ITaskAgent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/StartTaskStatus.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/StartTaskStatus.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskPool.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskPool.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskStatus.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskStatus.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/GenericVariable.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/GenericVariable.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/Variable.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/Variable.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.IVersionHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.IVersionHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.ConfigData.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.ConfigData.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.DataNode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.DataNode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNodeManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNodeManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.DataTable.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.DataTable.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataRow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataRow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTable.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTable.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.DebuggerWindowGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.DebuggerWindowGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindowGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindowGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/Constant.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/Constant.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperErrorEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperErrorEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadAgent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadAgent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTask.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTask.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTaskStatus.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTaskStatus.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInstanceObject.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInstanceObject.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityStatus.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityStatus.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.ShowEntityInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.ShowEntityInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/HideEntityCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/HideEntityCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntity.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntity.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroupHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroupHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntitySuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntitySuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/EventManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/EventManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/GameEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/GameEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/IEventManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/IEventManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/CommonFileSystemStream.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/CommonFileSystemStream.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.BlockData.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.BlockData.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.HeaderData.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.HeaderData.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.StringData.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.StringData.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemAccess.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemAccess.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemStream.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemStream.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystem.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystem.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/Fsm.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/Fsm.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmState.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmState.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsm.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsm.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsmManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsmManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/GameFramework.asmdef create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/GameFramework.asmdef.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/ICSharpCode.SharpZipLib.dll create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/ICSharpCode.SharpZipLib.dll.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/link.xml create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/link.xml.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/Language.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/Language.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/LocalizationManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/LocalizationManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/AddressFamily.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/AddressFamily.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannel.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannel.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannelHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannelHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHandler.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHandler.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHeader.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHeader.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkClosedEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkClosedEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkConnectedEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkConnectedEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkCustomErrorEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkCustomErrorEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorCode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorCode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ConnectState.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ConnectState.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.HeartBeatState.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.HeartBeatState.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.NetworkChannelBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.NetworkChannelBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ReceiveState.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ReceiveState.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.SendState.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.SendState.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpNetworkChannel.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpNetworkChannel.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkMissHeartBeatEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkMissHeartBeatEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/Packet.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/Packet.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/ServiceType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/ServiceType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPool.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPool.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPoolManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPoolManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.Object.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.Object.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ReleaseObjectFilterCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ReleaseObjectFilterCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/IProcedureManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/IProcedureManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties/AssemblyInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties/AssemblyInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ApplyResourcesCompleteCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ApplyResourcesCompleteCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckResourcesCompleteCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckResourcesCompleteCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckVersionListResult.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckVersionListResult.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/Constant.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/Constant.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/DecryptResourceCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/DecryptResourceCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/HasAssetResult.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/HasAssetResult.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ILoadResourceAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ILoadResourceAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroupCollection.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroupCollection.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/InitResourcesCompleteCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/InitResourcesCompleteCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetCallbacks.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetCallbacks.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetDependencyAssetCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetDependencyAssetCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetFailureCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetFailureCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetSuccessCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetSuccessCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetUpdateCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetUpdateCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryCallbacks.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryCallbacks.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryFailureCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryFailureCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinarySuccessCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinarySuccessCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesCallbacks.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesCallbacks.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesFailureCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesFailureCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesSuccessCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesSuccessCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperErrorEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperErrorEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperLoadCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperLoadCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperParseBytesCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperParseBytesCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadBytesCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadBytesCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadFileCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadFileCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceProgress.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceProgress.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceStatus.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceStatus.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneCallbacks.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneCallbacks.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneDependencyAssetCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneDependencyAssetCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneFailureCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneFailureCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneSuccessCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneSuccessCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneUpdateCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneUpdateCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.FileSystem.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.FileSystem.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.Resource.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.Resource.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Asset.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Asset.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.FileSystem.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.FileSystem.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Resource.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Resource.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.ResourceGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.ResourceGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionListSerializer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionListSerializer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadOnlyVersionListSerializer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadOnlyVersionListSerializer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadWriteVersionListSerializer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadWriteVersionListSerializer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplySuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplySuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.AssetInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.AssetInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.LoadType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.LoadType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ReadWriteResourceInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ReadWriteResourceInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.CheckStatus.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.CheckStatus.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.LocalVersionInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.LocalVersionInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.RemoteVersionInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.RemoteVersionInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroupCollection.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroupCollection.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceIniter.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceIniter.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadAssetTask.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadAssetTask.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadBinaryInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadBinaryInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadDependencyAssetTask.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadDependencyAssetTask.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceTaskBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceTaskBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadSceneTask.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadSceneTask.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.ResourceObject.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.ResourceObject.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceName.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceName.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceNameComparer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceNameComparer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.ApplyInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.ApplyInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.UpdateInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.UpdateInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.VerifyInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.VerifyInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.VersionListProcessor.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.VersionListProcessor.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceMode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceMode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.Resource.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.Resource.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionListSerializer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionListSerializer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateChangedEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateChangedEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifySuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifySuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneCallbacks.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneCallbacks.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneFailureCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneFailureCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneSuccessCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneSuccessCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Asset.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Asset.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.FileSystem.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.FileSystem.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Resource.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Resource.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.ResourceGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.ResourceGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionListSerializer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionListSerializer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateResourcesCompleteCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateResourcesCompleteCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListCallbacks.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListCallbacks.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListFailureCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListFailureCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListSuccessCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListSuccessCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/VerifyResourcesCompleteCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/VerifyResourcesCompleteCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/ISceneManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/ISceneManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/SceneManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/SceneManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/SettingManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/SettingManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/Constant.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/Constant.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroupHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroupHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundErrorCode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundErrorCode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundParams.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundParams.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ResetSoundAgentEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ResetSoundAgentEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.PlaySoundInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.PlaySoundInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundAgent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundAgent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/CloseUIFormCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/CloseUIFormCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIForm.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIForm.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIFormHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIFormHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroupHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroupHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.OpenUIFormInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.OpenUIFormInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIFormInstanceObject.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIFormInstanceObject.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.UIFormInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.UIFormInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Assembly.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Assembly.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.ICompressionHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.ICompressionHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Converter.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Converter.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Encryption.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Encryption.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.IJsonHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.IJsonHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Marshal.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Marshal.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Path.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Path.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Random.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Random.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.ITextHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.ITextHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.Crc32.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.Crc32.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/Constant.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/Constant.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperErrorEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperErrorEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestAgent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestAgent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTask.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTask.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTaskStatus.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTaskStatus.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/BaseComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/BaseComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameEntry.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameEntry.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameFrameworkComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameFrameworkComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/ShutdownType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/ShutdownType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/DefaultConfigHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/DefaultConfigHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode/DataNodeComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode/DataNodeComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataRowBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataRowBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DefaultDataTableHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DefaultDataTableHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerActiveWindowType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerActiveWindowType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ConsoleWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ConsoleWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.EnvironmentInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.EnvironmentInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.FpsCounter.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.FpsCounter.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.GraphicsInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.GraphicsInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputAccelerationInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputAccelerationInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputCompassInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputCompassInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputGyroscopeInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputGyroscopeInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputLocationInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputLocationInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputSummaryInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputSummaryInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputTouchInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputTouchInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.LogNode.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.LogNode.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.NetworkInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.NetworkInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ObjectPoolInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ObjectPoolInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.OperationsWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.OperationsWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.PathInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.PathInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ProfilerInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ProfilerInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.QualityInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.QualityInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ReferencePoolInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ReferencePoolInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.Sample.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.Sample.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.Record.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.Record.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SceneInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SceneInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScreenInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScreenInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScrollableDebuggerWindowBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScrollableDebuggerWindowBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SettingsWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SettingsWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SystemInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SystemInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.TimeInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.TimeInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.WebPlayerInformationWindow.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.WebPlayerInformationWindow.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadAgentHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadAgentHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.DownloadHandler.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.DownloadHandler.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/WWWDownloadAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/WWWDownloadAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/AttachEntityInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/AttachEntityInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityGroupHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityGroupHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/Entity.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/Entity.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.EntityGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.EntityGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityGroupHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityGroupHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityLogic.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityLogic.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/HideEntityCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/HideEntityCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntitySuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntitySuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event/EventComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event/EventComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/AndroidFileSystemStream.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/AndroidFileSystemStream.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/DefaultFileSystemHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/DefaultFileSystemHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm/FsmComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm/FsmComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/GameFramework.prefab create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/GameFramework.prefab.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/DefaultLocalizationHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/DefaultLocalizationHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionarySuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionarySuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkClosedEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkClosedEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkConnectedEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkConnectedEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkCustomErrorEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkCustomErrorEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkErrorEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkErrorEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkMissHeartBeatEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkMissHeartBeatEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool/ObjectPoolComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool/ObjectPoolComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure/ProcedureComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure/ProcedureComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferencePoolComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferencePoolComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferenceStrictCheckType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferenceStrictCheckType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListDeserializeCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListDeserializeCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListSerializeCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListSerializeCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListDeserializeCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListDeserializeCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListSerializeCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListSerializeCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultLoadResourceAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultLoadResourceAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultResourceHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultResourceHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/EditorResourceComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/EditorResourceComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/LoadResourceAgentHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/LoadResourceAgentHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ReadWritePathType.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ReadWritePathType.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplySuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplySuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateChangedEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateChangedEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifySuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifySuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/SceneAsset.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/SceneAsset.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/ActiveSceneChangedEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/ActiveSceneChangedEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/SceneComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/SceneComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSetting.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSetting.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingSerializer.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingSerializer.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/PlayerPrefsSettingHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/PlayerPrefsSettingHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundGroupHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundGroupHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundAgentHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundAgentHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.SoundGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.SoundGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundGroupHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundGroupHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/CloseUIFormCompleteEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/CloseUIFormCompleteEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIFormHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIFormHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIGroupHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIGroupHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormUpdateEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormUpdateEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.UIGroup.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.UIGroup.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIForm.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIForm.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormLogic.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormLogic.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIGroupHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIGroupHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIIntKey.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIIntKey.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIStringKey.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIStringKey.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UnityGameFramework.asmdef create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UnityGameFramework.asmdef.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/BinaryExtension.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/BinaryExtension.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultCompressionHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultCompressionHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultJsonHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultJsonHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultLogHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultLogHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultTextHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultTextHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultVersionHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultVersionHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Helper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Helper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Log.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Log.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/StringExtension.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/StringExtension.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/UnityExtension.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/UnityExtension.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarBoolean.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarBoolean.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByte.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByte.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByteArray.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByteArray.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarChar.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarChar.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarCharArray.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarCharArray.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor32.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor32.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDateTime.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDateTime.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDecimal.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDecimal.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDouble.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDouble.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarGameObject.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarGameObject.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt16.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt16.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt32.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt32.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt64.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt64.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarMaterial.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarMaterial.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarObject.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarObject.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarQuaternion.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarQuaternion.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarRect.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarRect.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSByte.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSByte.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSingle.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSingle.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarString.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarString.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTexture.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTexture.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTransform.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTransform.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt16.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt16.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt32.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt32.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt64.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt64.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUnityObject.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUnityObject.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector2.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector2.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector3.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector3.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector4.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector4.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/UnityWebRequestAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/UnityWebRequestAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWFormInfo.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWFormInfo.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWWebRequestAgentHelper.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWWebRequestAgentHelper.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestAgentHelperBase.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestAgentHelperBase.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestComponent.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestComponent.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestFailureEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestFailureEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestStartEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestStartEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestSuccessEventArgs.cs create mode 100644 Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestSuccessEventArgs.cs.meta create mode 100644 Packages/com.bywaystudios.gameframework/package.json create mode 100644 Packages/com.bywaystudios.gameframework/package.json.meta create mode 100644 Packages/manifest.json create mode 100644 Packages/packages-lock.json create mode 100644 ProjectSettings/AudioManager.asset create mode 100644 ProjectSettings/ClusterInputManager.asset create mode 100644 ProjectSettings/DynamicsManager.asset create mode 100644 ProjectSettings/EditorBuildSettings.asset create mode 100644 ProjectSettings/EditorSettings.asset create mode 100644 ProjectSettings/GraphicsSettings.asset create mode 100644 ProjectSettings/InputManager.asset create mode 100644 ProjectSettings/MemorySettings.asset create mode 100644 ProjectSettings/NavMeshAreas.asset create mode 100644 ProjectSettings/PackageManagerSettings.asset create mode 100644 ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json create mode 100644 ProjectSettings/Physics2DSettings.asset create mode 100644 ProjectSettings/PresetManager.asset create mode 100644 ProjectSettings/ProjectSettings.asset create mode 100644 ProjectSettings/ProjectVersion.txt create mode 100644 ProjectSettings/QualitySettings.asset create mode 100644 ProjectSettings/TagManager.asset create mode 100644 ProjectSettings/TimeManager.asset create mode 100644 ProjectSettings/UnityConnectSettings.asset create mode 100644 ProjectSettings/VFXManager.asset create mode 100644 ProjectSettings/VersionControlSettings.asset create mode 100644 ProjectSettings/XRSettings.asset diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff03d40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,106 @@ +# This .gitignore file should be placed at the root of your Unity project directory +# +# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore +# +.utmp/ +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Uu]ser[Ss]ettings/ +*.log + +# By default unity supports Blender asset imports, *.blend1 blender files do not need to be commited to version control. +*.blend1 +*.blend1.meta + +# MemoryCaptures can get excessive in size. +# They also could contain extremely sensitive data +/[Mm]emoryCaptures/ + +# Recordings can get excessive in size +/[Rr]ecordings/ + +# Uncomment this line if you wish to ignore the asset store tools plugin +# /[Aa]ssets/AssetStoreTools* + +# Autogenerated Jetbrains Rider plugin +/[Aa]ssets/Plugins/Editor/JetBrains* +# Jetbrains Rider personal-layer settings +*.DotSettings.user + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Mono auto generated files +mono_crash.* + +# Builds +*.apk +*.aab +*.unitypackage +*.unitypackage.meta + +# Crashlytics generated file +crashlytics-build.properties + +# TestRunner generated files +InitTestScene*.unity* + +# Addressables default ignores, before user customizations +/ServerData +/[Aa]ssets/StreamingAssets/aa* +/[Aa]ssets/AddressableAssetsData/link.xml* +/[Aa]ssets/Addressables_Temp* +# By default, Addressables content builds will generate addressables_content_state.bin +# files in platform-specific subfolders, for example: +# /Assets/AddressableAssetsData/OSX/addressables_content_state.bin +/[Aa]ssets/AddressableAssetsData/*/*.bin* + +# Visual Scripting auto-generated files +/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db +/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db.meta +/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers +/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers.meta + +# Auto-generated scenes by play mode tests +/[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity* + +.vsconfig + +Logs/ +[Aa]ssets/ +[Pp]ublish/ +.vscode/settings.json +*.dat \ No newline at end of file diff --git a/Packages/com.bywaystudios.gameframework/Editor.meta b/Packages/com.bywaystudios.gameframework/Editor.meta new file mode 100644 index 0000000..ceb638a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2aa138f4f4780094290a8c340776447a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector.meta new file mode 100644 index 0000000..06b4dd1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4a3909aead6c5da4d94aba08883f0562 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/BaseComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/BaseComponentInspector.cs new file mode 100644 index 0000000..65d3792 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/BaseComponentInspector.cs @@ -0,0 +1,319 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(BaseComponent))] + internal sealed class BaseComponentInspector : GameFrameworkInspector + { + private const string NoneOptionName = ""; + private static readonly float[] GameSpeed = new float[] { 0f, 0.01f, 0.1f, 0.25f, 0.5f, 1f, 1.5f, 2f, 4f, 8f }; + private static readonly string[] GameSpeedForDisplay = new string[] { "0x", "0.01x", "0.1x", "0.25x", "0.5x", "1x", "1.5x", "2x", "4x", "8x" }; + + private SerializedProperty m_EditorResourceMode = null; + private SerializedProperty m_EditorLanguage = null; + private SerializedProperty m_TextHelperTypeName = null; + private SerializedProperty m_VersionHelperTypeName = null; + private SerializedProperty m_LogHelperTypeName = null; + private SerializedProperty m_CompressionHelperTypeName = null; + private SerializedProperty m_JsonHelperTypeName = null; + private SerializedProperty m_FrameRate = null; + private SerializedProperty m_GameSpeed = null; + private SerializedProperty m_RunInBackground = null; + private SerializedProperty m_NeverSleep = null; + + private string[] m_TextHelperTypeNames = null; + private int m_TextHelperTypeNameIndex = 0; + private string[] m_VersionHelperTypeNames = null; + private int m_VersionHelperTypeNameIndex = 0; + private string[] m_LogHelperTypeNames = null; + private int m_LogHelperTypeNameIndex = 0; + private string[] m_CompressionHelperTypeNames = null; + private int m_CompressionHelperTypeNameIndex = 0; + private string[] m_JsonHelperTypeNames = null; + private int m_JsonHelperTypeNameIndex = 0; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + BaseComponent t = (BaseComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + m_EditorResourceMode.boolValue = EditorGUILayout.BeginToggleGroup("Editor Resource Mode", m_EditorResourceMode.boolValue); + { + EditorGUILayout.HelpBox("Editor resource mode option is only for editor mode. Game Framework will use editor resource files, which you should validate first.", MessageType.Warning); + EditorGUILayout.PropertyField(m_EditorLanguage); + EditorGUILayout.HelpBox("Editor language option is only use for localization test in editor mode.", MessageType.Info); + } + EditorGUILayout.EndToggleGroup(); + + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.LabelField("Global Helpers", EditorStyles.boldLabel); + + int textHelperSelectedIndex = EditorGUILayout.Popup("Text Helper", m_TextHelperTypeNameIndex, m_TextHelperTypeNames); + if (textHelperSelectedIndex != m_TextHelperTypeNameIndex) + { + m_TextHelperTypeNameIndex = textHelperSelectedIndex; + m_TextHelperTypeName.stringValue = textHelperSelectedIndex <= 0 ? null : m_TextHelperTypeNames[textHelperSelectedIndex]; + } + + int versionHelperSelectedIndex = EditorGUILayout.Popup("Version Helper", m_VersionHelperTypeNameIndex, m_VersionHelperTypeNames); + if (versionHelperSelectedIndex != m_VersionHelperTypeNameIndex) + { + m_VersionHelperTypeNameIndex = versionHelperSelectedIndex; + m_VersionHelperTypeName.stringValue = versionHelperSelectedIndex <= 0 ? null : m_VersionHelperTypeNames[versionHelperSelectedIndex]; + } + + int logHelperSelectedIndex = EditorGUILayout.Popup("Log Helper", m_LogHelperTypeNameIndex, m_LogHelperTypeNames); + if (logHelperSelectedIndex != m_LogHelperTypeNameIndex) + { + m_LogHelperTypeNameIndex = logHelperSelectedIndex; + m_LogHelperTypeName.stringValue = logHelperSelectedIndex <= 0 ? null : m_LogHelperTypeNames[logHelperSelectedIndex]; + } + + int compressionHelperSelectedIndex = EditorGUILayout.Popup("Compression Helper", m_CompressionHelperTypeNameIndex, m_CompressionHelperTypeNames); + if (compressionHelperSelectedIndex != m_CompressionHelperTypeNameIndex) + { + m_CompressionHelperTypeNameIndex = compressionHelperSelectedIndex; + m_CompressionHelperTypeName.stringValue = compressionHelperSelectedIndex <= 0 ? null : m_CompressionHelperTypeNames[compressionHelperSelectedIndex]; + } + + int jsonHelperSelectedIndex = EditorGUILayout.Popup("JSON Helper", m_JsonHelperTypeNameIndex, m_JsonHelperTypeNames); + if (jsonHelperSelectedIndex != m_JsonHelperTypeNameIndex) + { + m_JsonHelperTypeNameIndex = jsonHelperSelectedIndex; + m_JsonHelperTypeName.stringValue = jsonHelperSelectedIndex <= 0 ? null : m_JsonHelperTypeNames[jsonHelperSelectedIndex]; + } + } + EditorGUILayout.EndVertical(); + } + EditorGUI.EndDisabledGroup(); + + int frameRate = EditorGUILayout.IntSlider("Frame Rate", m_FrameRate.intValue, 1, 120); + if (frameRate != m_FrameRate.intValue) + { + if (EditorApplication.isPlaying) + { + t.FrameRate = frameRate; + } + else + { + m_FrameRate.intValue = frameRate; + } + } + + EditorGUILayout.BeginVertical("box"); + { + float gameSpeed = EditorGUILayout.Slider("Game Speed", m_GameSpeed.floatValue, 0f, 8f); + int selectedGameSpeed = GUILayout.SelectionGrid(GetSelectedGameSpeed(gameSpeed), GameSpeedForDisplay, 5); + if (selectedGameSpeed >= 0) + { + gameSpeed = GetGameSpeed(selectedGameSpeed); + } + + if (gameSpeed != m_GameSpeed.floatValue) + { + if (EditorApplication.isPlaying) + { + t.GameSpeed = gameSpeed; + } + else + { + m_GameSpeed.floatValue = gameSpeed; + } + } + } + EditorGUILayout.EndVertical(); + + bool runInBackground = EditorGUILayout.Toggle("Run in Background", m_RunInBackground.boolValue); + if (runInBackground != m_RunInBackground.boolValue) + { + if (EditorApplication.isPlaying) + { + t.RunInBackground = runInBackground; + } + else + { + m_RunInBackground.boolValue = runInBackground; + } + } + + bool neverSleep = EditorGUILayout.Toggle("Never Sleep", m_NeverSleep.boolValue); + if (neverSleep != m_NeverSleep.boolValue) + { + if (EditorApplication.isPlaying) + { + t.NeverSleep = neverSleep; + } + else + { + m_NeverSleep.boolValue = neverSleep; + } + } + + serializedObject.ApplyModifiedProperties(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_EditorResourceMode = serializedObject.FindProperty("m_EditorResourceMode"); + m_EditorLanguage = serializedObject.FindProperty("m_EditorLanguage"); + m_TextHelperTypeName = serializedObject.FindProperty("m_TextHelperTypeName"); + m_VersionHelperTypeName = serializedObject.FindProperty("m_VersionHelperTypeName"); + m_LogHelperTypeName = serializedObject.FindProperty("m_LogHelperTypeName"); + m_CompressionHelperTypeName = serializedObject.FindProperty("m_CompressionHelperTypeName"); + m_JsonHelperTypeName = serializedObject.FindProperty("m_JsonHelperTypeName"); + m_FrameRate = serializedObject.FindProperty("m_FrameRate"); + m_GameSpeed = serializedObject.FindProperty("m_GameSpeed"); + m_RunInBackground = serializedObject.FindProperty("m_RunInBackground"); + m_NeverSleep = serializedObject.FindProperty("m_NeverSleep"); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + List textHelperTypeNames = new List + { + NoneOptionName + }; + + textHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Utility.Text.ITextHelper))); + m_TextHelperTypeNames = textHelperTypeNames.ToArray(); + m_TextHelperTypeNameIndex = 0; + if (!string.IsNullOrEmpty(m_TextHelperTypeName.stringValue)) + { + m_TextHelperTypeNameIndex = textHelperTypeNames.IndexOf(m_TextHelperTypeName.stringValue); + if (m_TextHelperTypeNameIndex <= 0) + { + m_TextHelperTypeNameIndex = 0; + m_TextHelperTypeName.stringValue = null; + } + } + + List versionHelperTypeNames = new List + { + NoneOptionName + }; + + versionHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Version.IVersionHelper))); + m_VersionHelperTypeNames = versionHelperTypeNames.ToArray(); + m_VersionHelperTypeNameIndex = 0; + if (!string.IsNullOrEmpty(m_VersionHelperTypeName.stringValue)) + { + m_VersionHelperTypeNameIndex = versionHelperTypeNames.IndexOf(m_VersionHelperTypeName.stringValue); + if (m_VersionHelperTypeNameIndex <= 0) + { + m_VersionHelperTypeNameIndex = 0; + m_VersionHelperTypeName.stringValue = null; + } + } + + List logHelperTypeNames = new List + { + NoneOptionName + }; + + logHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(GameFrameworkLog.ILogHelper))); + m_LogHelperTypeNames = logHelperTypeNames.ToArray(); + m_LogHelperTypeNameIndex = 0; + if (!string.IsNullOrEmpty(m_LogHelperTypeName.stringValue)) + { + m_LogHelperTypeNameIndex = logHelperTypeNames.IndexOf(m_LogHelperTypeName.stringValue); + if (m_LogHelperTypeNameIndex <= 0) + { + m_LogHelperTypeNameIndex = 0; + m_LogHelperTypeName.stringValue = null; + } + } + + List compressionHelperTypeNames = new List + { + NoneOptionName + }; + + compressionHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Utility.Compression.ICompressionHelper))); + m_CompressionHelperTypeNames = compressionHelperTypeNames.ToArray(); + m_CompressionHelperTypeNameIndex = 0; + if (!string.IsNullOrEmpty(m_CompressionHelperTypeName.stringValue)) + { + m_CompressionHelperTypeNameIndex = compressionHelperTypeNames.IndexOf(m_CompressionHelperTypeName.stringValue); + if (m_CompressionHelperTypeNameIndex <= 0) + { + m_CompressionHelperTypeNameIndex = 0; + m_CompressionHelperTypeName.stringValue = null; + } + } + + List jsonHelperTypeNames = new List + { + NoneOptionName + }; + + jsonHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Utility.Json.IJsonHelper))); + m_JsonHelperTypeNames = jsonHelperTypeNames.ToArray(); + m_JsonHelperTypeNameIndex = 0; + if (!string.IsNullOrEmpty(m_JsonHelperTypeName.stringValue)) + { + m_JsonHelperTypeNameIndex = jsonHelperTypeNames.IndexOf(m_JsonHelperTypeName.stringValue); + if (m_JsonHelperTypeNameIndex <= 0) + { + m_JsonHelperTypeNameIndex = 0; + m_JsonHelperTypeName.stringValue = null; + } + } + + serializedObject.ApplyModifiedProperties(); + } + + private float GetGameSpeed(int selectedGameSpeed) + { + if (selectedGameSpeed < 0) + { + return GameSpeed[0]; + } + + if (selectedGameSpeed >= GameSpeed.Length) + { + return GameSpeed[GameSpeed.Length - 1]; + } + + return GameSpeed[selectedGameSpeed]; + } + + private int GetSelectedGameSpeed(float gameSpeed) + { + for (int i = 0; i < GameSpeed.Length; i++) + { + if (gameSpeed == GameSpeed[i]) + { + return i; + } + } + + return -1; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/BaseComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/BaseComponentInspector.cs.meta new file mode 100644 index 0000000..4d4704f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/BaseComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55195676d06c1cd418e6f3201eae7176 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ConfigComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ConfigComponentInspector.cs new file mode 100644 index 0000000..5773113 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ConfigComponentInspector.cs @@ -0,0 +1,74 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(ConfigComponent))] + internal sealed class ConfigComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_EnableLoadConfigUpdateEvent = null; + private SerializedProperty m_EnableLoadConfigDependencyAssetEvent = null; + private SerializedProperty m_CachedBytesSize = null; + + private HelperInfo m_ConfigHelperInfo = new HelperInfo("Config"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + ConfigComponent t = (ConfigComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_EnableLoadConfigUpdateEvent); + EditorGUILayout.PropertyField(m_EnableLoadConfigDependencyAssetEvent); + m_ConfigHelperInfo.Draw(); + EditorGUILayout.PropertyField(m_CachedBytesSize); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Config Count", t.Count.ToString()); + EditorGUILayout.LabelField("Cached Bytes Size", t.CachedBytesSize.ToString()); + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_EnableLoadConfigUpdateEvent = serializedObject.FindProperty("m_EnableLoadConfigUpdateEvent"); + m_EnableLoadConfigDependencyAssetEvent = serializedObject.FindProperty("m_EnableLoadConfigDependencyAssetEvent"); + m_CachedBytesSize = serializedObject.FindProperty("m_CachedBytesSize"); + + m_ConfigHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_ConfigHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ConfigComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ConfigComponentInspector.cs.meta new file mode 100644 index 0000000..5f39ce0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ConfigComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e450812c22c29141a8930ae4c8b7fe6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataNodeComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataNodeComponentInspector.cs new file mode 100644 index 0000000..e05775a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataNodeComponentInspector.cs @@ -0,0 +1,51 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.DataNode; +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(DataNodeComponent))] + internal sealed class DataNodeComponentInspector : GameFrameworkInspector + { + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + if (!EditorApplication.isPlaying) + { + EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info); + return; + } + + DataNodeComponent t = (DataNodeComponent)target; + + if (IsPrefabInHierarchy(t.gameObject)) + { + DrawDataNode(t.Root); + } + + Repaint(); + } + + private void OnEnable() + { + } + + private void DrawDataNode(IDataNode dataNode) + { + EditorGUILayout.LabelField(dataNode.FullName, dataNode.ToDataString()); + IDataNode[] child = dataNode.GetAllChild(); + foreach (IDataNode c in child) + { + DrawDataNode(c); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataNodeComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataNodeComponentInspector.cs.meta new file mode 100644 index 0000000..8fd492c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataNodeComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ce0d352bae82974e86bfe9010a4bdfd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataTableComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataTableComponentInspector.cs new file mode 100644 index 0000000..baf74af --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataTableComponentInspector.cs @@ -0,0 +1,87 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.DataTable; +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(DataTableComponent))] + internal sealed class DataTableComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_EnableLoadDataTableUpdateEvent = null; + private SerializedProperty m_EnableLoadDataTableDependencyAssetEvent = null; + private SerializedProperty m_CachedBytesSize = null; + + private HelperInfo m_DataTableHelperInfo = new HelperInfo("DataTable"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + DataTableComponent t = (DataTableComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_EnableLoadDataTableUpdateEvent); + EditorGUILayout.PropertyField(m_EnableLoadDataTableDependencyAssetEvent); + m_DataTableHelperInfo.Draw(); + EditorGUILayout.PropertyField(m_CachedBytesSize); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Data Table Count", t.Count.ToString()); + EditorGUILayout.LabelField("Cached Bytes Size", t.CachedBytesSize.ToString()); + + DataTableBase[] dataTables = t.GetAllDataTables(); + foreach (DataTableBase dataTable in dataTables) + { + DrawDataTable(dataTable); + } + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_EnableLoadDataTableUpdateEvent = serializedObject.FindProperty("m_EnableLoadDataTableUpdateEvent"); + m_EnableLoadDataTableDependencyAssetEvent = serializedObject.FindProperty("m_EnableLoadDataTableDependencyAssetEvent"); + m_CachedBytesSize = serializedObject.FindProperty("m_CachedBytesSize"); + + m_DataTableHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void DrawDataTable(DataTableBase dataTable) + { + EditorGUILayout.LabelField(dataTable.FullName, Utility.Text.Format("{0} Rows", dataTable.Count)); + } + + private void RefreshTypeNames() + { + m_DataTableHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataTableComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataTableComponentInspector.cs.meta new file mode 100644 index 0000000..e53932d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DataTableComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75e2902c828fd8a4cb81e6d743351074 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/DebuggerComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DebuggerComponentInspector.cs new file mode 100644 index 0000000..b3cb54d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DebuggerComponentInspector.cs @@ -0,0 +1,68 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(DebuggerComponent))] + internal sealed class DebuggerComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_Skin = null; + private SerializedProperty m_ActiveWindow = null; + private SerializedProperty m_ShowFullWindow = null; + private SerializedProperty m_ConsoleWindow = null; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + DebuggerComponent t = (DebuggerComponent)target; + + EditorGUILayout.PropertyField(m_Skin); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + bool activeWindow = EditorGUILayout.Toggle("Active Window", t.ActiveWindow); + if (activeWindow != t.ActiveWindow) + { + t.ActiveWindow = activeWindow; + } + } + else + { + EditorGUILayout.PropertyField(m_ActiveWindow); + } + + EditorGUILayout.PropertyField(m_ShowFullWindow); + + if (EditorApplication.isPlaying) + { + if (GUILayout.Button("Reset Layout")) + { + t.ResetLayout(); + } + } + + EditorGUILayout.PropertyField(m_ConsoleWindow, true); + + serializedObject.ApplyModifiedProperties(); + } + + private void OnEnable() + { + m_Skin = serializedObject.FindProperty("m_Skin"); + m_ActiveWindow = serializedObject.FindProperty("m_ActiveWindow"); + m_ShowFullWindow = serializedObject.FindProperty("m_ShowFullWindow"); + m_ConsoleWindow = serializedObject.FindProperty("m_ConsoleWindow"); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/DebuggerComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DebuggerComponentInspector.cs.meta new file mode 100644 index 0000000..dfec8f9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DebuggerComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 482ae76a43c942249953b4c30ec4859b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/DownloadComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DownloadComponentInspector.cs new file mode 100644 index 0000000..0eb16b4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DownloadComponentInspector.cs @@ -0,0 +1,156 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(DownloadComponent))] + internal sealed class DownloadComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_InstanceRoot = null; + private SerializedProperty m_DownloadAgentHelperCount = null; + private SerializedProperty m_Timeout = null; + private SerializedProperty m_FlushSize = null; + + private HelperInfo m_DownloadAgentHelperInfo = new HelperInfo("DownloadAgent"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + DownloadComponent t = (DownloadComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_InstanceRoot); + m_DownloadAgentHelperInfo.Draw(); + m_DownloadAgentHelperCount.intValue = EditorGUILayout.IntSlider("Download Agent Helper Count", m_DownloadAgentHelperCount.intValue, 1, 16); + } + EditorGUI.EndDisabledGroup(); + + float timeout = EditorGUILayout.Slider("Timeout", m_Timeout.floatValue, 0f, 120f); + if (timeout != m_Timeout.floatValue) + { + if (EditorApplication.isPlaying) + { + t.Timeout = timeout; + } + else + { + m_Timeout.floatValue = timeout; + } + } + + int flushSize = EditorGUILayout.DelayedIntField("Flush Size", m_FlushSize.intValue); + if (flushSize != m_FlushSize.intValue) + { + if (EditorApplication.isPlaying) + { + t.FlushSize = flushSize; + } + else + { + m_FlushSize.intValue = flushSize; + } + } + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Paused", t.Paused.ToString()); + EditorGUILayout.LabelField("Total Agent Count", t.TotalAgentCount.ToString()); + EditorGUILayout.LabelField("Free Agent Count", t.FreeAgentCount.ToString()); + EditorGUILayout.LabelField("Working Agent Count", t.WorkingAgentCount.ToString()); + EditorGUILayout.LabelField("Waiting Agent Count", t.WaitingTaskCount.ToString()); + EditorGUILayout.LabelField("Current Speed", t.CurrentSpeed.ToString()); + EditorGUILayout.BeginVertical("box"); + { + TaskInfo[] downloadInfos = t.GetAllDownloadInfos(); + if (downloadInfos.Length > 0) + { + foreach (TaskInfo downloadInfo in downloadInfos) + { + DrawDownloadInfo(downloadInfo); + } + + if (GUILayout.Button("Export CSV Data")) + { + string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, "Download Task Data.csv", string.Empty); + if (!string.IsNullOrEmpty(exportFileName)) + { + try + { + int index = 0; + string[] data = new string[downloadInfos.Length + 1]; + data[index++] = "Download Path,Serial Id,Tag,Priority,Status"; + foreach (TaskInfo downloadInfo in downloadInfos) + { + data[index++] = Utility.Text.Format("{0},{1},{2},{3},{4}", downloadInfo.Description, downloadInfo.SerialId, downloadInfo.Tag ?? string.Empty, downloadInfo.Priority, downloadInfo.Status); + } + + File.WriteAllLines(exportFileName, data, Encoding.UTF8); + Debug.Log(Utility.Text.Format("Export download task CSV data to '{0}' success.", exportFileName)); + } + catch (Exception exception) + { + Debug.LogError(Utility.Text.Format("Export download task CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception)); + } + } + } + } + else + { + GUILayout.Label("Download Task is Empty ..."); + } + } + EditorGUILayout.EndVertical(); + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot"); + m_DownloadAgentHelperCount = serializedObject.FindProperty("m_DownloadAgentHelperCount"); + m_Timeout = serializedObject.FindProperty("m_Timeout"); + m_FlushSize = serializedObject.FindProperty("m_FlushSize"); + + m_DownloadAgentHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void DrawDownloadInfo(TaskInfo downloadInfo) + { + EditorGUILayout.LabelField(downloadInfo.Description, Utility.Text.Format("[SerialId]{0} [Tag]{1} [Priority]{2} [Status]{3}", downloadInfo.SerialId, downloadInfo.Tag ?? "", downloadInfo.Priority, downloadInfo.Status)); + } + + private void RefreshTypeNames() + { + m_DownloadAgentHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/DownloadComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DownloadComponentInspector.cs.meta new file mode 100644 index 0000000..77c77c7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/DownloadComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e008c434c24c414cbee0f9e5191702e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/EditorResourceComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EditorResourceComponentInspector.cs new file mode 100644 index 0000000..9d3b3e2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EditorResourceComponentInspector.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(EditorResourceComponent))] + internal sealed class EditorResourceComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_EnableCachedAssets = null; + private SerializedProperty m_LoadAssetCountPerFrame = null; + private SerializedProperty m_MinLoadAssetRandomDelaySeconds = null; + private SerializedProperty m_MaxLoadAssetRandomDelaySeconds = null; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + EditorResourceComponent t = (EditorResourceComponent)target; + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Load Waiting Asset Count", t.LoadWaitingAssetCount.ToString()); + } + + EditorGUILayout.PropertyField(m_EnableCachedAssets); + EditorGUILayout.PropertyField(m_LoadAssetCountPerFrame); + EditorGUILayout.PropertyField(m_MinLoadAssetRandomDelaySeconds); + EditorGUILayout.PropertyField(m_MaxLoadAssetRandomDelaySeconds); + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + private void OnEnable() + { + m_EnableCachedAssets = serializedObject.FindProperty("m_EnableCachedAssets"); + m_LoadAssetCountPerFrame = serializedObject.FindProperty("m_LoadAssetCountPerFrame"); + m_MinLoadAssetRandomDelaySeconds = serializedObject.FindProperty("m_MinLoadAssetRandomDelaySeconds"); + m_MaxLoadAssetRandomDelaySeconds = serializedObject.FindProperty("m_MaxLoadAssetRandomDelaySeconds"); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/EditorResourceComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EditorResourceComponentInspector.cs.meta new file mode 100644 index 0000000..1fe3447 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EditorResourceComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e657cda935f6f7409a2486383dd3208 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/EntityComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EntityComponentInspector.cs new file mode 100644 index 0000000..13427ae --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EntityComponentInspector.cs @@ -0,0 +1,88 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Entity; +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(EntityComponent))] + internal sealed class EntityComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_EnableShowEntityUpdateEvent = null; + private SerializedProperty m_EnableShowEntityDependencyAssetEvent = null; + private SerializedProperty m_InstanceRoot = null; + private SerializedProperty m_EntityGroups = null; + + private HelperInfo m_EntityHelperInfo = new HelperInfo("Entity"); + private HelperInfo m_EntityGroupHelperInfo = new HelperInfo("EntityGroup"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + EntityComponent t = (EntityComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_EnableShowEntityUpdateEvent); + EditorGUILayout.PropertyField(m_EnableShowEntityDependencyAssetEvent); + EditorGUILayout.PropertyField(m_InstanceRoot); + m_EntityHelperInfo.Draw(); + m_EntityGroupHelperInfo.Draw(); + EditorGUILayout.PropertyField(m_EntityGroups, true); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Entity Group Count", t.EntityGroupCount.ToString()); + EditorGUILayout.LabelField("Entity Count (Total)", t.EntityCount.ToString()); + IEntityGroup[] entityGroups = t.GetAllEntityGroups(); + foreach (IEntityGroup entityGroup in entityGroups) + { + EditorGUILayout.LabelField(Utility.Text.Format("Entity Count ({0})", entityGroup.Name), entityGroup.EntityCount.ToString()); + } + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_EnableShowEntityUpdateEvent = serializedObject.FindProperty("m_EnableShowEntityUpdateEvent"); + m_EnableShowEntityDependencyAssetEvent = serializedObject.FindProperty("m_EnableShowEntityDependencyAssetEvent"); + m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot"); + m_EntityGroups = serializedObject.FindProperty("m_EntityGroups"); + + m_EntityHelperInfo.Init(serializedObject); + m_EntityGroupHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_EntityHelperInfo.Refresh(); + m_EntityGroupHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/EntityComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EntityComponentInspector.cs.meta new file mode 100644 index 0000000..4fdfeb6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EntityComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 692b0cef6071a1342b8cc4e6ab9a2fb1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/EventComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EventComponentInspector.cs new file mode 100644 index 0000000..a085344 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EventComponentInspector.cs @@ -0,0 +1,41 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(EventComponent))] + internal sealed class EventComponentInspector : GameFrameworkInspector + { + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + if (!EditorApplication.isPlaying) + { + EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info); + return; + } + + EventComponent t = (EventComponent)target; + + if (IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Event Handler Count", t.EventHandlerCount.ToString()); + EditorGUILayout.LabelField("Event Count", t.EventCount.ToString()); + } + + Repaint(); + } + + private void OnEnable() + { + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/EventComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EventComponentInspector.cs.meta new file mode 100644 index 0000000..0d573e3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/EventComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb23c608d69039c4dab132437b577ba1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/FileSystemComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/FileSystemComponentInspector.cs new file mode 100644 index 0000000..649e4ee --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/FileSystemComponentInspector.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.FileSystem; +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(FileSystemComponent))] + internal sealed class FileSystemComponentInspector : GameFrameworkInspector + { + private HelperInfo m_FileSystemHelperInfo = new HelperInfo("FileSystem"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + FileSystemComponent t = (FileSystemComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + m_FileSystemHelperInfo.Draw(); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("File System Count", t.Count.ToString()); + + IFileSystem[] fileSystems = t.GetAllFileSystems(); + foreach (IFileSystem fileSystem in fileSystems) + { + DrawFileSystem(fileSystem); + } + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_FileSystemHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_FileSystemHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + + private void DrawFileSystem(IFileSystem fileSystem) + { + EditorGUILayout.LabelField(fileSystem.FullPath, Utility.Text.Format("{0}, {1} / {2} Files", fileSystem.Access, fileSystem.FileCount, fileSystem.MaxFileCount)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/FileSystemComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/FileSystemComponentInspector.cs.meta new file mode 100644 index 0000000..2080778 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/FileSystemComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc83fe4d1e4c1ae41bdd9881023a44a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/FsmComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/FsmComponentInspector.cs new file mode 100644 index 0000000..91960db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/FsmComponentInspector.cs @@ -0,0 +1,53 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Fsm; +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(FsmComponent))] + internal sealed class FsmComponentInspector : GameFrameworkInspector + { + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + if (!EditorApplication.isPlaying) + { + EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info); + return; + } + + FsmComponent t = (FsmComponent)target; + + if (IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("FSM Count", t.Count.ToString()); + + FsmBase[] fsms = t.GetAllFsms(); + foreach (FsmBase fsm in fsms) + { + DrawFsm(fsm); + } + } + + Repaint(); + } + + private void OnEnable() + { + } + + private void DrawFsm(FsmBase fsm) + { + EditorGUILayout.LabelField(fsm.FullName, fsm.IsRunning ? Utility.Text.Format("{0}, {1:F1} s", fsm.CurrentStateName, fsm.CurrentStateTime) : (fsm.IsDestroyed ? "Destroyed" : "Not Running")); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/FsmComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/FsmComponentInspector.cs.meta new file mode 100644 index 0000000..1d1389e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/FsmComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 581c356e8f25d484792c21435f5794aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/GameFrameworkInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/GameFrameworkInspector.cs new file mode 100644 index 0000000..421fd7c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/GameFrameworkInspector.cs @@ -0,0 +1,64 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; + +namespace UnityGameFramework.Editor +{ + /// + /// 游戏框架 Inspector 抽象类。 + /// + public abstract class GameFrameworkInspector : UnityEditor.Editor + { + private bool m_IsCompiling = false; + + /// + /// 绘制事件。 + /// + public override void OnInspectorGUI() + { + if (m_IsCompiling && !EditorApplication.isCompiling) + { + m_IsCompiling = false; + OnCompileComplete(); + } + else if (!m_IsCompiling && EditorApplication.isCompiling) + { + m_IsCompiling = true; + OnCompileStart(); + } + } + + /// + /// 编译开始事件。 + /// + protected virtual void OnCompileStart() + { + } + + /// + /// 编译完成事件。 + /// + protected virtual void OnCompileComplete() + { + } + + protected bool IsPrefabInHierarchy(UnityEngine.Object obj) + { + if (obj == null) + { + return false; + } + +#if UNITY_2018_3_OR_NEWER + return PrefabUtility.GetPrefabAssetType(obj) != PrefabAssetType.Regular; +#else + return PrefabUtility.GetPrefabType(obj) != PrefabType.Prefab; +#endif + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/GameFrameworkInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/GameFrameworkInspector.cs.meta new file mode 100644 index 0000000..5052ceb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/GameFrameworkInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5bb373d9bcd4bd45861670fa5208e05 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/LocalizationComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/LocalizationComponentInspector.cs new file mode 100644 index 0000000..3bacb67 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/LocalizationComponentInspector.cs @@ -0,0 +1,76 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(LocalizationComponent))] + internal sealed class LocalizationComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_EnableLoadDictionaryUpdateEvent = null; + private SerializedProperty m_EnableLoadDictionaryDependencyAssetEvent = null; + private SerializedProperty m_CachedBytesSize = null; + + private HelperInfo m_LocalizationHelperInfo = new HelperInfo("Localization"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + LocalizationComponent t = (LocalizationComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_EnableLoadDictionaryUpdateEvent); + EditorGUILayout.PropertyField(m_EnableLoadDictionaryDependencyAssetEvent); + m_LocalizationHelperInfo.Draw(); + EditorGUILayout.PropertyField(m_CachedBytesSize); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Language", t.Language.ToString()); + EditorGUILayout.LabelField("System Language", t.SystemLanguage.ToString()); + EditorGUILayout.LabelField("Dictionary Count", t.DictionaryCount.ToString()); + EditorGUILayout.LabelField("Cached Bytes Size", t.CachedBytesSize.ToString()); + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_EnableLoadDictionaryUpdateEvent = serializedObject.FindProperty("m_EnableLoadDictionaryUpdateEvent"); + m_EnableLoadDictionaryDependencyAssetEvent = serializedObject.FindProperty("m_EnableLoadDictionaryDependencyAssetEvent"); + m_CachedBytesSize = serializedObject.FindProperty("m_CachedBytesSize"); + + m_LocalizationHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_LocalizationHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/LocalizationComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/LocalizationComponentInspector.cs.meta new file mode 100644 index 0000000..0d4401a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/LocalizationComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e90ad13aae4116347b57e87e5d00c94d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/NetworkComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/NetworkComponentInspector.cs new file mode 100644 index 0000000..8b5c31a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/NetworkComponentInspector.cs @@ -0,0 +1,76 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Network; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(NetworkComponent))] + internal sealed class NetworkComponentInspector : GameFrameworkInspector + { + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + if (!EditorApplication.isPlaying) + { + EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info); + return; + } + + NetworkComponent t = (NetworkComponent)target; + + if (IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString()); + + INetworkChannel[] networkChannels = t.GetAllNetworkChannels(); + foreach (INetworkChannel networkChannel in networkChannels) + { + DrawNetworkChannel(networkChannel); + } + } + + Repaint(); + } + + private void OnEnable() + { + } + + private void DrawNetworkChannel(INetworkChannel networkChannel) + { + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected"); + EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString()); + EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString()); + EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable"); + EditorGUILayout.LabelField("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable"); + EditorGUILayout.LabelField("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount, networkChannel.SentPacketCount)); + EditorGUILayout.LabelField("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount, networkChannel.ReceivedPacketCount)); + EditorGUILayout.LabelField("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString()); + EditorGUILayout.LabelField("Heart Beat", Utility.Text.Format("{0:F2} / {1:F2}", networkChannel.HeartBeatElapseSeconds, networkChannel.HeartBeatInterval)); + EditorGUI.BeginDisabledGroup(!networkChannel.Connected); + { + if (GUILayout.Button("Disconnect")) + { + networkChannel.Close(); + } + } + EditorGUI.EndDisabledGroup(); + } + EditorGUILayout.EndVertical(); + + EditorGUILayout.Separator(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/NetworkComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/NetworkComponentInspector.cs.meta new file mode 100644 index 0000000..1e13b26 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/NetworkComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7cbb7330261939244ac0b87d6798313a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ObjectPoolComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ObjectPoolComponentInspector.cs new file mode 100644 index 0000000..8628c1f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ObjectPoolComponentInspector.cs @@ -0,0 +1,138 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.ObjectPool; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(ObjectPoolComponent))] + internal sealed class ObjectPoolComponentInspector : GameFrameworkInspector + { + private readonly HashSet m_OpenedItems = new HashSet(); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + if (!EditorApplication.isPlaying) + { + EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info); + return; + } + + ObjectPoolComponent t = (ObjectPoolComponent)target; + + if (IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Object Pool Count", t.Count.ToString()); + + ObjectPoolBase[] objectPools = t.GetAllObjectPools(true); + foreach (ObjectPoolBase objectPool in objectPools) + { + DrawObjectPool(objectPool); + } + } + + Repaint(); + } + + private void OnEnable() + { + } + + private void DrawObjectPool(ObjectPoolBase objectPool) + { + bool lastState = m_OpenedItems.Contains(objectPool.FullName); + bool currentState = EditorGUILayout.Foldout(lastState, objectPool.FullName); + if (currentState != lastState) + { + if (currentState) + { + m_OpenedItems.Add(objectPool.FullName); + } + else + { + m_OpenedItems.Remove(objectPool.FullName); + } + } + + if (currentState) + { + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.LabelField("Name", objectPool.Name); + EditorGUILayout.LabelField("Type", objectPool.ObjectType.FullName); + EditorGUILayout.LabelField("Auto Release Interval", objectPool.AutoReleaseInterval.ToString()); + EditorGUILayout.LabelField("Capacity", objectPool.Capacity.ToString()); + EditorGUILayout.LabelField("Used Count", objectPool.Count.ToString()); + EditorGUILayout.LabelField("Can Release Count", objectPool.CanReleaseCount.ToString()); + EditorGUILayout.LabelField("Expire Time", objectPool.ExpireTime.ToString()); + EditorGUILayout.LabelField("Priority", objectPool.Priority.ToString()); + ObjectInfo[] objectInfos = objectPool.GetAllObjectInfos(); + if (objectInfos.Length > 0) + { + EditorGUILayout.LabelField("Name", objectPool.AllowMultiSpawn ? "Locked\tCount\tFlag\tPriority\tLast Use Time" : "Locked\tIn Use\tFlag\tPriority\tLast Use Time"); + foreach (ObjectInfo objectInfo in objectInfos) + { + EditorGUILayout.LabelField(string.IsNullOrEmpty(objectInfo.Name) ? "" : objectInfo.Name, objectPool.AllowMultiSpawn ? Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4:yyyy-MM-dd HH:mm:ss}", objectInfo.Locked, objectInfo.SpawnCount, objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime()) : Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4:yyyy-MM-dd HH:mm:ss}", objectInfo.Locked, objectInfo.IsInUse, objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime())); + } + + if (GUILayout.Button("Release")) + { + objectPool.Release(); + } + + if (GUILayout.Button("Release All Unused")) + { + objectPool.ReleaseAllUnused(); + } + + if (GUILayout.Button("Export CSV Data")) + { + string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, Utility.Text.Format("Object Pool Data - {0}.csv", objectPool.Name), string.Empty); + if (!string.IsNullOrEmpty(exportFileName)) + { + try + { + int index = 0; + string[] data = new string[objectInfos.Length + 1]; + data[index++] = Utility.Text.Format("Name,Locked,{0},Custom Can Release Flag,Priority,Last Use Time", objectPool.AllowMultiSpawn ? "Count" : "In Use"); + foreach (ObjectInfo objectInfo in objectInfos) + { + data[index++] = objectPool.AllowMultiSpawn ? Utility.Text.Format("{0},{1},{2},{3},{4},{5:yyyy-MM-dd HH:mm:ss}", objectInfo.Name, objectInfo.Locked, objectInfo.SpawnCount, objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime()) : Utility.Text.Format("{0},{1},{2},{3},{4},{5:yyyy-MM-dd HH:mm:ss}", objectInfo.Name, objectInfo.Locked, objectInfo.IsInUse, objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime()); + } + + File.WriteAllLines(exportFileName, data, Encoding.UTF8); + Debug.Log(Utility.Text.Format("Export object pool CSV data to '{0}' success.", exportFileName)); + } + catch (Exception exception) + { + Debug.LogError(Utility.Text.Format("Export object pool CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception)); + } + } + } + } + else + { + GUILayout.Label("Object Pool is Empty ..."); + } + } + EditorGUILayout.EndVertical(); + + EditorGUILayout.Separator(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ObjectPoolComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ObjectPoolComponentInspector.cs.meta new file mode 100644 index 0000000..26a3673 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ObjectPoolComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb0d4111d9ba0ad469b2361c7731666a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ProcedureComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ProcedureComponentInspector.cs new file mode 100644 index 0000000..664c1d9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ProcedureComponentInspector.cs @@ -0,0 +1,172 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Procedure; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(ProcedureComponent))] + internal sealed class ProcedureComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_AvailableProcedureTypeNames = null; + private SerializedProperty m_EntranceProcedureTypeName = null; + + private string[] m_ProcedureTypeNames = null; + private List m_CurrentAvailableProcedureTypeNames = null; + private int m_EntranceProcedureIndex = -1; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + ProcedureComponent t = (ProcedureComponent)target; + + if (string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue)) + { + EditorGUILayout.HelpBox("Entrance procedure is invalid.", MessageType.Error); + } + else if (EditorApplication.isPlaying) + { + EditorGUILayout.LabelField("Current Procedure", t.CurrentProcedure == null ? "None" : t.CurrentProcedure.GetType().ToString()); + } + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + GUILayout.Label("Available Procedures", EditorStyles.boldLabel); + if (m_ProcedureTypeNames.Length > 0) + { + EditorGUILayout.BeginVertical("box"); + { + foreach (string procedureTypeName in m_ProcedureTypeNames) + { + bool selected = m_CurrentAvailableProcedureTypeNames.Contains(procedureTypeName); + if (selected != EditorGUILayout.ToggleLeft(procedureTypeName, selected)) + { + if (!selected) + { + m_CurrentAvailableProcedureTypeNames.Add(procedureTypeName); + WriteAvailableProcedureTypeNames(); + } + else if (procedureTypeName != m_EntranceProcedureTypeName.stringValue) + { + m_CurrentAvailableProcedureTypeNames.Remove(procedureTypeName); + WriteAvailableProcedureTypeNames(); + } + } + } + } + EditorGUILayout.EndVertical(); + } + else + { + EditorGUILayout.HelpBox("There is no available procedure.", MessageType.Warning); + } + + if (m_CurrentAvailableProcedureTypeNames.Count > 0) + { + EditorGUILayout.Separator(); + + int selectedIndex = EditorGUILayout.Popup("Entrance Procedure", m_EntranceProcedureIndex, m_CurrentAvailableProcedureTypeNames.ToArray()); + if (selectedIndex != m_EntranceProcedureIndex) + { + m_EntranceProcedureIndex = selectedIndex; + m_EntranceProcedureTypeName.stringValue = m_CurrentAvailableProcedureTypeNames[selectedIndex]; + } + } + else + { + EditorGUILayout.HelpBox("Select available procedures first.", MessageType.Info); + } + } + EditorGUI.EndDisabledGroup(); + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_AvailableProcedureTypeNames = serializedObject.FindProperty("m_AvailableProcedureTypeNames"); + m_EntranceProcedureTypeName = serializedObject.FindProperty("m_EntranceProcedureTypeName"); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_ProcedureTypeNames = Type.GetRuntimeTypeNames(typeof(ProcedureBase)); + ReadAvailableProcedureTypeNames(); + int oldCount = m_CurrentAvailableProcedureTypeNames.Count; + m_CurrentAvailableProcedureTypeNames = m_CurrentAvailableProcedureTypeNames.Where(x => m_ProcedureTypeNames.Contains(x)).ToList(); + if (m_CurrentAvailableProcedureTypeNames.Count != oldCount) + { + WriteAvailableProcedureTypeNames(); + } + else if (!string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue)) + { + m_EntranceProcedureIndex = m_CurrentAvailableProcedureTypeNames.IndexOf(m_EntranceProcedureTypeName.stringValue); + if (m_EntranceProcedureIndex < 0) + { + m_EntranceProcedureTypeName.stringValue = null; + } + } + + serializedObject.ApplyModifiedProperties(); + } + + private void ReadAvailableProcedureTypeNames() + { + m_CurrentAvailableProcedureTypeNames = new List(); + int count = m_AvailableProcedureTypeNames.arraySize; + for (int i = 0; i < count; i++) + { + m_CurrentAvailableProcedureTypeNames.Add(m_AvailableProcedureTypeNames.GetArrayElementAtIndex(i).stringValue); + } + } + + private void WriteAvailableProcedureTypeNames() + { + m_AvailableProcedureTypeNames.ClearArray(); + if (m_CurrentAvailableProcedureTypeNames == null) + { + return; + } + + m_CurrentAvailableProcedureTypeNames.Sort(); + int count = m_CurrentAvailableProcedureTypeNames.Count; + for (int i = 0; i < count; i++) + { + m_AvailableProcedureTypeNames.InsertArrayElementAtIndex(i); + m_AvailableProcedureTypeNames.GetArrayElementAtIndex(i).stringValue = m_CurrentAvailableProcedureTypeNames[i]; + } + + if (!string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue)) + { + m_EntranceProcedureIndex = m_CurrentAvailableProcedureTypeNames.IndexOf(m_EntranceProcedureTypeName.stringValue); + if (m_EntranceProcedureIndex < 0) + { + m_EntranceProcedureTypeName.stringValue = null; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ProcedureComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ProcedureComponentInspector.cs.meta new file mode 100644 index 0000000..c391625 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ProcedureComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 64d014b25074fd64b995dd8a458b6973 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ReferencePoolComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ReferencePoolComponentInspector.cs new file mode 100644 index 0000000..c5dc3a1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ReferencePoolComponentInspector.cs @@ -0,0 +1,152 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(ReferencePoolComponent))] + internal sealed class ReferencePoolComponentInspector : GameFrameworkInspector + { + private readonly Dictionary> m_ReferencePoolInfos = new Dictionary>(StringComparer.Ordinal); + private readonly HashSet m_OpenedItems = new HashSet(); + + private SerializedProperty m_EnableStrictCheck = null; + + private bool m_ShowFullClassName = false; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + ReferencePoolComponent t = (ReferencePoolComponent)target; + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + bool enableStrictCheck = EditorGUILayout.Toggle("Enable Strict Check", t.EnableStrictCheck); + if (enableStrictCheck != t.EnableStrictCheck) + { + t.EnableStrictCheck = enableStrictCheck; + } + + EditorGUILayout.LabelField("Reference Pool Count", ReferencePool.Count.ToString()); + m_ShowFullClassName = EditorGUILayout.Toggle("Show Full Class Name", m_ShowFullClassName); + m_ReferencePoolInfos.Clear(); + ReferencePoolInfo[] referencePoolInfos = ReferencePool.GetAllReferencePoolInfos(); + foreach (ReferencePoolInfo referencePoolInfo in referencePoolInfos) + { + string assemblyName = referencePoolInfo.Type.Assembly.GetName().Name; + List results = null; + if (!m_ReferencePoolInfos.TryGetValue(assemblyName, out results)) + { + results = new List(); + m_ReferencePoolInfos.Add(assemblyName, results); + } + + results.Add(referencePoolInfo); + } + + foreach (KeyValuePair> assemblyReferencePoolInfo in m_ReferencePoolInfos) + { + bool lastState = m_OpenedItems.Contains(assemblyReferencePoolInfo.Key); + bool currentState = EditorGUILayout.Foldout(lastState, assemblyReferencePoolInfo.Key); + if (currentState != lastState) + { + if (currentState) + { + m_OpenedItems.Add(assemblyReferencePoolInfo.Key); + } + else + { + m_OpenedItems.Remove(assemblyReferencePoolInfo.Key); + } + } + + if (currentState) + { + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.LabelField(m_ShowFullClassName ? "Full Class Name" : "Class Name", "Unused\tUsing\tAcquire\tRelease\tAdd\tRemove"); + assemblyReferencePoolInfo.Value.Sort(Comparison); + foreach (ReferencePoolInfo referencePoolInfo in assemblyReferencePoolInfo.Value) + { + DrawReferencePoolInfo(referencePoolInfo); + } + + if (GUILayout.Button("Export CSV Data")) + { + string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, Utility.Text.Format("Reference Pool Data - {0}.csv", assemblyReferencePoolInfo.Key), string.Empty); + if (!string.IsNullOrEmpty(exportFileName)) + { + try + { + int index = 0; + string[] data = new string[assemblyReferencePoolInfo.Value.Count + 1]; + data[index++] = "Class Name,Full Class Name,Unused,Using,Acquire,Release,Add,Remove"; + foreach (ReferencePoolInfo referencePoolInfo in assemblyReferencePoolInfo.Value) + { + data[index++] = Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7}", referencePoolInfo.Type.Name, referencePoolInfo.Type.FullName, referencePoolInfo.UnusedReferenceCount, referencePoolInfo.UsingReferenceCount, referencePoolInfo.AcquireReferenceCount, referencePoolInfo.ReleaseReferenceCount, referencePoolInfo.AddReferenceCount, referencePoolInfo.RemoveReferenceCount); + } + + File.WriteAllLines(exportFileName, data, Encoding.UTF8); + Debug.Log(Utility.Text.Format("Export reference pool CSV data to '{0}' success.", exportFileName)); + } + catch (Exception exception) + { + Debug.LogError(Utility.Text.Format("Export reference pool CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception)); + } + } + } + } + EditorGUILayout.EndVertical(); + + EditorGUILayout.Separator(); + } + } + } + else + { + EditorGUILayout.PropertyField(m_EnableStrictCheck); + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + private void OnEnable() + { + m_EnableStrictCheck = serializedObject.FindProperty("m_EnableStrictCheck"); + } + + private void DrawReferencePoolInfo(ReferencePoolInfo referencePoolInfo) + { + EditorGUILayout.LabelField(m_ShowFullClassName ? referencePoolInfo.Type.FullName : referencePoolInfo.Type.Name, Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", referencePoolInfo.UnusedReferenceCount, referencePoolInfo.UsingReferenceCount, referencePoolInfo.AcquireReferenceCount, referencePoolInfo.ReleaseReferenceCount, referencePoolInfo.AddReferenceCount, referencePoolInfo.RemoveReferenceCount)); + } + + private int Comparison(ReferencePoolInfo a, ReferencePoolInfo b) + { + if (m_ShowFullClassName) + { + return a.Type.FullName.CompareTo(b.Type.FullName); + } + else + { + return a.Type.Name.CompareTo(b.Type.Name); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ReferencePoolComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ReferencePoolComponentInspector.cs.meta new file mode 100644 index 0000000..defecb2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ReferencePoolComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 705a7441224da3d4cbc6593bdc58f167 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ResourceComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ResourceComponentInspector.cs new file mode 100644 index 0000000..9bcda9e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ResourceComponentInspector.cs @@ -0,0 +1,397 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.IO; +using System.Reflection; +using System.Text; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(ResourceComponent))] + internal sealed class ResourceComponentInspector : GameFrameworkInspector + { + private static readonly string[] ResourceModeNames = new string[] { "Package", "Updatable", "Updatable While Playing" }; + + private SerializedProperty m_ResourceMode = null; + private SerializedProperty m_ReadWritePathType = null; + private SerializedProperty m_MinUnloadUnusedAssetsInterval = null; + private SerializedProperty m_MaxUnloadUnusedAssetsInterval = null; + private SerializedProperty m_AssetAutoReleaseInterval = null; + private SerializedProperty m_AssetCapacity = null; + private SerializedProperty m_AssetExpireTime = null; + private SerializedProperty m_AssetPriority = null; + private SerializedProperty m_ResourceAutoReleaseInterval = null; + private SerializedProperty m_ResourceCapacity = null; + private SerializedProperty m_ResourceExpireTime = null; + private SerializedProperty m_ResourcePriority = null; + private SerializedProperty m_UpdatePrefixUri = null; + private SerializedProperty m_GenerateReadWriteVersionListLength = null; + private SerializedProperty m_UpdateRetryCount = null; + private SerializedProperty m_InstanceRoot = null; + private SerializedProperty m_LoadResourceAgentHelperCount = null; + + private FieldInfo m_EditorResourceModeFieldInfo = null; + + private int m_ResourceModeIndex = 0; + private HelperInfo m_ResourceHelperInfo = new HelperInfo("Resource"); + private HelperInfo m_LoadResourceAgentHelperInfo = new HelperInfo("LoadResourceAgent"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + ResourceComponent t = (ResourceComponent)target; + + bool isEditorResourceMode = (bool)m_EditorResourceModeFieldInfo.GetValue(target); + + if (isEditorResourceMode) + { + EditorGUILayout.HelpBox("Editor resource mode is enabled. Some options are disabled.", MessageType.Warning); + } + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.EnumPopup("Resource Mode", t.ResourceMode); + } + else + { + int selectedIndex = EditorGUILayout.Popup("Resource Mode", m_ResourceModeIndex, ResourceModeNames); + if (selectedIndex != m_ResourceModeIndex) + { + m_ResourceModeIndex = selectedIndex; + m_ResourceMode.enumValueIndex = selectedIndex + 1; + } + } + + m_ReadWritePathType.enumValueIndex = (int)(ReadWritePathType)EditorGUILayout.EnumPopup("Read-Write Path Type", t.ReadWritePathType); + } + EditorGUI.EndDisabledGroup(); + + float minUnloadUnusedAssetsInterval = EditorGUILayout.Slider("Min Unload Unused Assets Interval", m_MinUnloadUnusedAssetsInterval.floatValue, 0f, 3600f); + if (minUnloadUnusedAssetsInterval != m_MinUnloadUnusedAssetsInterval.floatValue) + { + if (EditorApplication.isPlaying) + { + t.MinUnloadUnusedAssetsInterval = minUnloadUnusedAssetsInterval; + } + else + { + m_MinUnloadUnusedAssetsInterval.floatValue = minUnloadUnusedAssetsInterval; + } + } + + float maxUnloadUnusedAssetsInterval = EditorGUILayout.Slider("Max Unload Unused Assets Interval", m_MaxUnloadUnusedAssetsInterval.floatValue, 0f, 3600f); + if (maxUnloadUnusedAssetsInterval != m_MaxUnloadUnusedAssetsInterval.floatValue) + { + if (EditorApplication.isPlaying) + { + t.MaxUnloadUnusedAssetsInterval = maxUnloadUnusedAssetsInterval; + } + else + { + m_MaxUnloadUnusedAssetsInterval.floatValue = maxUnloadUnusedAssetsInterval; + } + } + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying && isEditorResourceMode); + { + float assetAutoReleaseInterval = EditorGUILayout.DelayedFloatField("Asset Auto Release Interval", m_AssetAutoReleaseInterval.floatValue); + if (assetAutoReleaseInterval != m_AssetAutoReleaseInterval.floatValue) + { + if (EditorApplication.isPlaying) + { + t.AssetAutoReleaseInterval = assetAutoReleaseInterval; + } + else + { + m_AssetAutoReleaseInterval.floatValue = assetAutoReleaseInterval; + } + } + + int assetCapacity = EditorGUILayout.DelayedIntField("Asset Capacity", m_AssetCapacity.intValue); + if (assetCapacity != m_AssetCapacity.intValue) + { + if (EditorApplication.isPlaying) + { + t.AssetCapacity = assetCapacity; + } + else + { + m_AssetCapacity.intValue = assetCapacity; + } + } + + float assetExpireTime = EditorGUILayout.DelayedFloatField("Asset Expire Time", m_AssetExpireTime.floatValue); + if (assetExpireTime != m_AssetExpireTime.floatValue) + { + if (EditorApplication.isPlaying) + { + t.AssetExpireTime = assetExpireTime; + } + else + { + m_AssetExpireTime.floatValue = assetExpireTime; + } + } + + int assetPriority = EditorGUILayout.DelayedIntField("Asset Priority", m_AssetPriority.intValue); + if (assetPriority != m_AssetPriority.intValue) + { + if (EditorApplication.isPlaying) + { + t.AssetPriority = assetPriority; + } + else + { + m_AssetPriority.intValue = assetPriority; + } + } + + float resourceAutoReleaseInterval = EditorGUILayout.DelayedFloatField("Resource Auto Release Interval", m_ResourceAutoReleaseInterval.floatValue); + if (resourceAutoReleaseInterval != m_ResourceAutoReleaseInterval.floatValue) + { + if (EditorApplication.isPlaying) + { + t.ResourceAutoReleaseInterval = resourceAutoReleaseInterval; + } + else + { + m_ResourceAutoReleaseInterval.floatValue = resourceAutoReleaseInterval; + } + } + + int resourceCapacity = EditorGUILayout.DelayedIntField("Resource Capacity", m_ResourceCapacity.intValue); + if (resourceCapacity != m_ResourceCapacity.intValue) + { + if (EditorApplication.isPlaying) + { + t.ResourceCapacity = resourceCapacity; + } + else + { + m_ResourceCapacity.intValue = resourceCapacity; + } + } + + float resourceExpireTime = EditorGUILayout.DelayedFloatField("Resource Expire Time", m_ResourceExpireTime.floatValue); + if (resourceExpireTime != m_ResourceExpireTime.floatValue) + { + if (EditorApplication.isPlaying) + { + t.ResourceExpireTime = resourceExpireTime; + } + else + { + m_ResourceExpireTime.floatValue = resourceExpireTime; + } + } + + int resourcePriority = EditorGUILayout.DelayedIntField("Resource Priority", m_ResourcePriority.intValue); + if (resourcePriority != m_ResourcePriority.intValue) + { + if (EditorApplication.isPlaying) + { + t.ResourcePriority = resourcePriority; + } + else + { + m_ResourcePriority.intValue = resourcePriority; + } + } + + if (m_ResourceModeIndex > 0) + { + string updatePrefixUri = EditorGUILayout.DelayedTextField("Update Prefix Uri", m_UpdatePrefixUri.stringValue); + if (updatePrefixUri != m_UpdatePrefixUri.stringValue) + { + if (EditorApplication.isPlaying) + { + t.UpdatePrefixUri = updatePrefixUri; + } + else + { + m_UpdatePrefixUri.stringValue = updatePrefixUri; + } + } + + int generateReadWriteVersionListLength = EditorGUILayout.DelayedIntField("Generate Read-Write Version List Length", m_GenerateReadWriteVersionListLength.intValue); + if (generateReadWriteVersionListLength != m_GenerateReadWriteVersionListLength.intValue) + { + if (EditorApplication.isPlaying) + { + t.GenerateReadWriteVersionListLength = generateReadWriteVersionListLength; + } + else + { + m_GenerateReadWriteVersionListLength.intValue = generateReadWriteVersionListLength; + } + } + + int updateRetryCount = EditorGUILayout.DelayedIntField("Update Retry Count", m_UpdateRetryCount.intValue); + if (updateRetryCount != m_UpdateRetryCount.intValue) + { + if (EditorApplication.isPlaying) + { + t.UpdateRetryCount = updateRetryCount; + } + else + { + m_UpdateRetryCount.intValue = updateRetryCount; + } + } + } + } + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_InstanceRoot); + + m_ResourceHelperInfo.Draw(); + m_LoadResourceAgentHelperInfo.Draw(); + m_LoadResourceAgentHelperCount.intValue = EditorGUILayout.IntSlider("Load Resource Agent Helper Count", m_LoadResourceAgentHelperCount.intValue, 1, 128); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Unload Unused Assets", Utility.Text.Format("{0:F2} / {1:F2}", t.LastUnloadUnusedAssetsOperationElapseSeconds, t.MaxUnloadUnusedAssetsInterval)); + EditorGUILayout.LabelField("Read-Only Path", t.ReadOnlyPath.ToString()); + EditorGUILayout.LabelField("Read-Write Path", t.ReadWritePath.ToString()); + EditorGUILayout.LabelField("Current Variant", t.CurrentVariant ?? ""); + EditorGUILayout.LabelField("Applicable Game Version", isEditorResourceMode ? "N/A" : t.ApplicableGameVersion ?? ""); + EditorGUILayout.LabelField("Internal Resource Version", isEditorResourceMode ? "N/A" : t.InternalResourceVersion.ToString()); + EditorGUILayout.LabelField("Asset Count", isEditorResourceMode ? "N/A" : t.AssetCount.ToString()); + EditorGUILayout.LabelField("Resource Count", isEditorResourceMode ? "N/A" : t.ResourceCount.ToString()); + EditorGUILayout.LabelField("Resource Group Count", isEditorResourceMode ? "N/A" : t.ResourceGroupCount.ToString()); + if (m_ResourceModeIndex > 0) + { + EditorGUILayout.LabelField("Applying Resource Pack Path", isEditorResourceMode ? "N/A" : t.ApplyingResourcePackPath ?? ""); + EditorGUILayout.LabelField("Apply Waiting Count", isEditorResourceMode ? "N/A" : t.ApplyWaitingCount.ToString()); + EditorGUILayout.LabelField("Updating Resource Group", isEditorResourceMode ? "N/A" : t.UpdatingResourceGroup != null ? t.UpdatingResourceGroup.Name : ""); + EditorGUILayout.LabelField("Update Waiting Count", isEditorResourceMode ? "N/A" : t.UpdateWaitingCount.ToString()); + EditorGUILayout.LabelField("Update Waiting While Playing Count", isEditorResourceMode ? "N/A" : t.UpdateWaitingWhilePlayingCount.ToString()); + EditorGUILayout.LabelField("Update Candidate Count", isEditorResourceMode ? "N/A" : t.UpdateCandidateCount.ToString()); + } + EditorGUILayout.LabelField("Load Total Agent Count", isEditorResourceMode ? "N/A" : t.LoadTotalAgentCount.ToString()); + EditorGUILayout.LabelField("Load Free Agent Count", isEditorResourceMode ? "N/A" : t.LoadFreeAgentCount.ToString()); + EditorGUILayout.LabelField("Load Working Agent Count", isEditorResourceMode ? "N/A" : t.LoadWorkingAgentCount.ToString()); + EditorGUILayout.LabelField("Load Waiting Task Count", isEditorResourceMode ? "N/A" : t.LoadWaitingTaskCount.ToString()); + if (!isEditorResourceMode) + { + EditorGUILayout.BeginVertical("box"); + { + TaskInfo[] loadAssetInfos = t.GetAllLoadAssetInfos(); + if (loadAssetInfos.Length > 0) + { + foreach (TaskInfo loadAssetInfo in loadAssetInfos) + { + DrawLoadAssetInfo(loadAssetInfo); + } + + if (GUILayout.Button("Export CSV Data")) + { + string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, "Load Asset Task Data.csv", string.Empty); + if (!string.IsNullOrEmpty(exportFileName)) + { + try + { + int index = 0; + string[] data = new string[loadAssetInfos.Length + 1]; + data[index++] = "Load Asset Name,Serial Id,Priority,Status"; + foreach (TaskInfo loadAssetInfo in loadAssetInfos) + { + data[index++] = Utility.Text.Format("{0},{1},{2},{3}", loadAssetInfo.Description, loadAssetInfo.SerialId, loadAssetInfo.Priority, loadAssetInfo.Status); + } + + File.WriteAllLines(exportFileName, data, Encoding.UTF8); + Debug.Log(Utility.Text.Format("Export load asset task CSV data to '{0}' success.", exportFileName)); + } + catch (Exception exception) + { + Debug.LogError(Utility.Text.Format("Export load asset task CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception)); + } + } + } + } + else + { + GUILayout.Label("Load Asset Task is Empty ..."); + } + } + EditorGUILayout.EndVertical(); + } + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_ResourceMode = serializedObject.FindProperty("m_ResourceMode"); + m_ReadWritePathType = serializedObject.FindProperty("m_ReadWritePathType"); + m_MinUnloadUnusedAssetsInterval = serializedObject.FindProperty("m_MinUnloadUnusedAssetsInterval"); + m_MaxUnloadUnusedAssetsInterval = serializedObject.FindProperty("m_MaxUnloadUnusedAssetsInterval"); + m_AssetAutoReleaseInterval = serializedObject.FindProperty("m_AssetAutoReleaseInterval"); + m_AssetCapacity = serializedObject.FindProperty("m_AssetCapacity"); + m_AssetExpireTime = serializedObject.FindProperty("m_AssetExpireTime"); + m_AssetPriority = serializedObject.FindProperty("m_AssetPriority"); + m_ResourceAutoReleaseInterval = serializedObject.FindProperty("m_ResourceAutoReleaseInterval"); + m_ResourceCapacity = serializedObject.FindProperty("m_ResourceCapacity"); + m_ResourceExpireTime = serializedObject.FindProperty("m_ResourceExpireTime"); + m_ResourcePriority = serializedObject.FindProperty("m_ResourcePriority"); + m_UpdatePrefixUri = serializedObject.FindProperty("m_UpdatePrefixUri"); + m_GenerateReadWriteVersionListLength = serializedObject.FindProperty("m_GenerateReadWriteVersionListLength"); + m_UpdateRetryCount = serializedObject.FindProperty("m_UpdateRetryCount"); + m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot"); + m_LoadResourceAgentHelperCount = serializedObject.FindProperty("m_LoadResourceAgentHelperCount"); + + m_EditorResourceModeFieldInfo = target.GetType().GetField("m_EditorResourceMode", BindingFlags.NonPublic | BindingFlags.Instance); + + m_ResourceHelperInfo.Init(serializedObject); + m_LoadResourceAgentHelperInfo.Init(serializedObject); + + RefreshModes(); + RefreshTypeNames(); + } + + private void DrawLoadAssetInfo(TaskInfo loadAssetInfo) + { + EditorGUILayout.LabelField(loadAssetInfo.Description, Utility.Text.Format("[SerialId]{0} [Priority]{1} [Status]{2}", loadAssetInfo.SerialId, loadAssetInfo.Priority, loadAssetInfo.Status)); + } + + private void RefreshModes() + { + m_ResourceModeIndex = m_ResourceMode.enumValueIndex > 0 ? m_ResourceMode.enumValueIndex - 1 : 0; + } + + private void RefreshTypeNames() + { + m_ResourceHelperInfo.Refresh(); + m_LoadResourceAgentHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/ResourceComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ResourceComponentInspector.cs.meta new file mode 100644 index 0000000..f6bbc5c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/ResourceComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ccae18b98b018e4baa1cb3063cece63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/SceneComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SceneComponentInspector.cs new file mode 100644 index 0000000..4d38bec --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SceneComponentInspector.cs @@ -0,0 +1,75 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(SceneComponent))] + internal sealed class SceneComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_EnableLoadSceneUpdateEvent = null; + private SerializedProperty m_EnableLoadSceneDependencyAssetEvent = null; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + SceneComponent t = (SceneComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_EnableLoadSceneUpdateEvent); + EditorGUILayout.PropertyField(m_EnableLoadSceneDependencyAssetEvent); + } + EditorGUI.EndDisabledGroup(); + + serializedObject.ApplyModifiedProperties(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Loaded Scene Asset Names", GetSceneNameString(t.GetLoadedSceneAssetNames())); + EditorGUILayout.LabelField("Loading Scene Asset Names", GetSceneNameString(t.GetLoadingSceneAssetNames())); + EditorGUILayout.LabelField("Unloading Scene Asset Names", GetSceneNameString(t.GetUnloadingSceneAssetNames())); + EditorGUILayout.ObjectField("Main Camera", t.MainCamera, typeof(Camera), true); + + Repaint(); + } + } + + private void OnEnable() + { + m_EnableLoadSceneUpdateEvent = serializedObject.FindProperty("m_EnableLoadSceneUpdateEvent"); + m_EnableLoadSceneDependencyAssetEvent = serializedObject.FindProperty("m_EnableLoadSceneDependencyAssetEvent"); + } + + private string GetSceneNameString(string[] sceneAssetNames) + { + if (sceneAssetNames == null || sceneAssetNames.Length <= 0) + { + return ""; + } + + string sceneNameString = string.Empty; + foreach (string sceneAssetName in sceneAssetNames) + { + if (!string.IsNullOrEmpty(sceneNameString)) + { + sceneNameString += ", "; + } + + sceneNameString += SceneComponent.GetSceneName(sceneAssetName); + } + + return sceneNameString; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/SceneComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SceneComponentInspector.cs.meta new file mode 100644 index 0000000..fd15fb3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SceneComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91ac1b5e58b58c843bcdf37998e18bcd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/SettingComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SettingComponentInspector.cs new file mode 100644 index 0000000..5d16bda --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SettingComponentInspector.cs @@ -0,0 +1,81 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(SettingComponent))] + internal sealed class SettingComponentInspector : GameFrameworkInspector + { + private HelperInfo m_SettingHelperInfo = new HelperInfo("Setting"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + SettingComponent t = (SettingComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + m_SettingHelperInfo.Draw(); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Setting Count", t.Count >= 0 ? t.Count.ToString() : ""); + if (t.Count > 0) + { + string[] settingNames = t.GetAllSettingNames(); + foreach (string settingName in settingNames) + { + EditorGUILayout.LabelField(settingName, t.GetString(settingName)); + } + } + } + + if (EditorApplication.isPlaying) + { + if (GUILayout.Button("Save Settings")) + { + t.Save(); + } + if (GUILayout.Button("Remove All Settings")) + { + t.RemoveAllSettings(); + } + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_SettingHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_SettingHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/SettingComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SettingComponentInspector.cs.meta new file mode 100644 index 0000000..ad940eb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SettingComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 079e17267e9ff8d489d7647323861ce8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/SoundComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SoundComponentInspector.cs new file mode 100644 index 0000000..c83e50e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SoundComponentInspector.cs @@ -0,0 +1,87 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(SoundComponent))] + internal sealed class SoundComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_EnablePlaySoundUpdateEvent = null; + private SerializedProperty m_EnablePlaySoundDependencyAssetEvent = null; + private SerializedProperty m_InstanceRoot = null; + private SerializedProperty m_AudioMixer = null; + private SerializedProperty m_SoundGroups = null; + + private HelperInfo m_SoundHelperInfo = new HelperInfo("Sound"); + private HelperInfo m_SoundGroupHelperInfo = new HelperInfo("SoundGroup"); + private HelperInfo m_SoundAgentHelperInfo = new HelperInfo("SoundAgent"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + SoundComponent t = (SoundComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_EnablePlaySoundUpdateEvent); + EditorGUILayout.PropertyField(m_EnablePlaySoundDependencyAssetEvent); + EditorGUILayout.PropertyField(m_InstanceRoot); + EditorGUILayout.PropertyField(m_AudioMixer); + m_SoundHelperInfo.Draw(); + m_SoundGroupHelperInfo.Draw(); + m_SoundAgentHelperInfo.Draw(); + EditorGUILayout.PropertyField(m_SoundGroups, true); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Sound Group Count", t.SoundGroupCount.ToString()); + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_EnablePlaySoundUpdateEvent = serializedObject.FindProperty("m_EnablePlaySoundUpdateEvent"); + m_EnablePlaySoundDependencyAssetEvent = serializedObject.FindProperty("m_EnablePlaySoundDependencyAssetEvent"); + m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot"); + m_AudioMixer = serializedObject.FindProperty("m_AudioMixer"); + m_SoundGroups = serializedObject.FindProperty("m_SoundGroups"); + + m_SoundHelperInfo.Init(serializedObject); + m_SoundGroupHelperInfo.Init(serializedObject); + m_SoundAgentHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_SoundHelperInfo.Refresh(); + m_SoundGroupHelperInfo.Refresh(); + m_SoundAgentHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/SoundComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SoundComponentInspector.cs.meta new file mode 100644 index 0000000..e2bdf69 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/SoundComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cba40a4571929b14098014e7b931c2ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/UIComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/UIComponentInspector.cs new file mode 100644 index 0000000..0f700ca --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/UIComponentInspector.cs @@ -0,0 +1,154 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(UIComponent))] + internal sealed class UIComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_EnableOpenUIFormSuccessEvent = null; + private SerializedProperty m_EnableOpenUIFormFailureEvent = null; + private SerializedProperty m_EnableOpenUIFormUpdateEvent = null; + private SerializedProperty m_EnableOpenUIFormDependencyAssetEvent = null; + private SerializedProperty m_EnableCloseUIFormCompleteEvent = null; + private SerializedProperty m_InstanceAutoReleaseInterval = null; + private SerializedProperty m_InstanceCapacity = null; + private SerializedProperty m_InstanceExpireTime = null; + private SerializedProperty m_InstancePriority = null; + private SerializedProperty m_InstanceRoot = null; + private SerializedProperty m_UIGroups = null; + + private HelperInfo m_UIFormHelperInfo = new HelperInfo("UIForm"); + private HelperInfo m_UIGroupHelperInfo = new HelperInfo("UIGroup"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + UIComponent t = (UIComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_EnableOpenUIFormSuccessEvent); + EditorGUILayout.PropertyField(m_EnableOpenUIFormFailureEvent); + EditorGUILayout.PropertyField(m_EnableOpenUIFormUpdateEvent); + EditorGUILayout.PropertyField(m_EnableOpenUIFormDependencyAssetEvent); + EditorGUILayout.PropertyField(m_EnableCloseUIFormCompleteEvent); + } + EditorGUI.EndDisabledGroup(); + + float instanceAutoReleaseInterval = EditorGUILayout.DelayedFloatField("Instance Auto Release Interval", m_InstanceAutoReleaseInterval.floatValue); + if (instanceAutoReleaseInterval != m_InstanceAutoReleaseInterval.floatValue) + { + if (EditorApplication.isPlaying) + { + t.InstanceAutoReleaseInterval = instanceAutoReleaseInterval; + } + else + { + m_InstanceAutoReleaseInterval.floatValue = instanceAutoReleaseInterval; + } + } + + int instanceCapacity = EditorGUILayout.DelayedIntField("Instance Capacity", m_InstanceCapacity.intValue); + if (instanceCapacity != m_InstanceCapacity.intValue) + { + if (EditorApplication.isPlaying) + { + t.InstanceCapacity = instanceCapacity; + } + else + { + m_InstanceCapacity.intValue = instanceCapacity; + } + } + + float instanceExpireTime = EditorGUILayout.DelayedFloatField("Instance Expire Time", m_InstanceExpireTime.floatValue); + if (instanceExpireTime != m_InstanceExpireTime.floatValue) + { + if (EditorApplication.isPlaying) + { + t.InstanceExpireTime = instanceExpireTime; + } + else + { + m_InstanceExpireTime.floatValue = instanceExpireTime; + } + } + + int instancePriority = EditorGUILayout.DelayedIntField("Instance Priority", m_InstancePriority.intValue); + if (instancePriority != m_InstancePriority.intValue) + { + if (EditorApplication.isPlaying) + { + t.InstancePriority = instancePriority; + } + else + { + m_InstancePriority.intValue = instancePriority; + } + } + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_InstanceRoot); + m_UIFormHelperInfo.Draw(); + m_UIGroupHelperInfo.Draw(); + EditorGUILayout.PropertyField(m_UIGroups, true); + } + EditorGUI.EndDisabledGroup(); + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("UI Group Count", t.UIGroupCount.ToString()); + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_EnableOpenUIFormSuccessEvent = serializedObject.FindProperty("m_EnableOpenUIFormSuccessEvent"); + m_EnableOpenUIFormFailureEvent = serializedObject.FindProperty("m_EnableOpenUIFormFailureEvent"); + m_EnableOpenUIFormUpdateEvent = serializedObject.FindProperty("m_EnableOpenUIFormUpdateEvent"); + m_EnableOpenUIFormDependencyAssetEvent = serializedObject.FindProperty("m_EnableOpenUIFormDependencyAssetEvent"); + m_EnableCloseUIFormCompleteEvent = serializedObject.FindProperty("m_EnableCloseUIFormCompleteEvent"); + m_InstanceAutoReleaseInterval = serializedObject.FindProperty("m_InstanceAutoReleaseInterval"); + m_InstanceCapacity = serializedObject.FindProperty("m_InstanceCapacity"); + m_InstanceExpireTime = serializedObject.FindProperty("m_InstanceExpireTime"); + m_InstancePriority = serializedObject.FindProperty("m_InstancePriority"); + m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot"); + m_UIGroups = serializedObject.FindProperty("m_UIGroups"); + + m_UIFormHelperInfo.Init(serializedObject); + m_UIGroupHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void RefreshTypeNames() + { + m_UIFormHelperInfo.Refresh(); + m_UIGroupHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/UIComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/UIComponentInspector.cs.meta new file mode 100644 index 0000000..4e077c6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/UIComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ae3c7028e65d19458efb14da7adf64b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/WebRequestComponentInspector.cs b/Packages/com.bywaystudios.gameframework/Editor/Inspector/WebRequestComponentInspector.cs new file mode 100644 index 0000000..e82ad8d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/WebRequestComponentInspector.cs @@ -0,0 +1,141 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor +{ + [CustomEditor(typeof(WebRequestComponent))] + internal sealed class WebRequestComponentInspector : GameFrameworkInspector + { + private SerializedProperty m_InstanceRoot = null; + private SerializedProperty m_WebRequestAgentHelperCount = null; + private SerializedProperty m_Timeout = null; + + private HelperInfo m_WebRequestAgentHelperInfo = new HelperInfo("WebRequestAgent"); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + serializedObject.Update(); + + WebRequestComponent t = (WebRequestComponent)target; + + EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); + { + EditorGUILayout.PropertyField(m_InstanceRoot); + + m_WebRequestAgentHelperInfo.Draw(); + + m_WebRequestAgentHelperCount.intValue = EditorGUILayout.IntSlider("Web Request Agent Helper Count", m_WebRequestAgentHelperCount.intValue, 1, 16); + } + EditorGUI.EndDisabledGroup(); + + float timeout = EditorGUILayout.Slider("Timeout", m_Timeout.floatValue, 0f, 120f); + if (timeout != m_Timeout.floatValue) + { + if (EditorApplication.isPlaying) + { + t.Timeout = timeout; + } + else + { + m_Timeout.floatValue = timeout; + } + } + + if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Total Agent Count", t.TotalAgentCount.ToString()); + EditorGUILayout.LabelField("Free Agent Count", t.FreeAgentCount.ToString()); + EditorGUILayout.LabelField("Working Agent Count", t.WorkingAgentCount.ToString()); + EditorGUILayout.LabelField("Waiting Agent Count", t.WaitingTaskCount.ToString()); + EditorGUILayout.BeginVertical("box"); + { + TaskInfo[] webRequestInfos = t.GetAllWebRequestInfos(); + if (webRequestInfos.Length > 0) + { + foreach (TaskInfo webRequestInfo in webRequestInfos) + { + DrawWebRequestInfo(webRequestInfo); + } + + if (GUILayout.Button("Export CSV Data")) + { + string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, "WebRequest Task Data.csv", string.Empty); + if (!string.IsNullOrEmpty(exportFileName)) + { + try + { + int index = 0; + string[] data = new string[webRequestInfos.Length + 1]; + data[index++] = "WebRequest Uri,Serial Id,Tag,Priority,Status"; + foreach (TaskInfo webRequestInfo in webRequestInfos) + { + data[index++] = Utility.Text.Format("{0},{1},{2},{3},{4}", webRequestInfo.Description, webRequestInfo.SerialId, webRequestInfo.Tag ?? string.Empty, webRequestInfo.Priority, webRequestInfo.Status); + } + + File.WriteAllLines(exportFileName, data, Encoding.UTF8); + Debug.Log(Utility.Text.Format("Export web request task CSV data to '{0}' success.", exportFileName)); + } + catch (Exception exception) + { + Debug.LogError(Utility.Text.Format("Export web request task CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception)); + } + } + } + } + else + { + GUILayout.Label("WebRequset Task is Empty ..."); + } + } + EditorGUILayout.EndVertical(); + } + + serializedObject.ApplyModifiedProperties(); + + Repaint(); + } + + protected override void OnCompileComplete() + { + base.OnCompileComplete(); + + RefreshTypeNames(); + } + + private void OnEnable() + { + m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot"); + m_WebRequestAgentHelperCount = serializedObject.FindProperty("m_WebRequestAgentHelperCount"); + m_Timeout = serializedObject.FindProperty("m_Timeout"); + + m_WebRequestAgentHelperInfo.Init(serializedObject); + + RefreshTypeNames(); + } + + private void DrawWebRequestInfo(TaskInfo webRequestInfo) + { + EditorGUILayout.LabelField(webRequestInfo.Description, Utility.Text.Format("[SerialId]{0} [Tag]{1} [Priority]{2} [Status]{3}", webRequestInfo.SerialId, webRequestInfo.Tag ?? "", webRequestInfo.Priority, webRequestInfo.Status)); + } + + private void RefreshTypeNames() + { + m_WebRequestAgentHelperInfo.Refresh(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Inspector/WebRequestComponentInspector.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Inspector/WebRequestComponentInspector.cs.meta new file mode 100644 index 0000000..20ee463 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Inspector/WebRequestComponentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbb0e62b54d44b74dab4b9a49e186d0f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc.meta new file mode 100644 index 0000000..5bb2b39 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 491d19006ebbf6248832da552a08c5be +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettings.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettings.cs new file mode 100644 index 0000000..9f05dea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettings.cs @@ -0,0 +1,133 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor +{ + /// + /// 构建配置相关的实用函数。 + /// + internal static class BuildSettings + { + private static readonly string s_ConfigurationPath = null; + private static readonly List s_DefaultSceneNames = new List(); + private static readonly List s_SearchScenePaths = new List(); + + static BuildSettings() + { + s_ConfigurationPath = Type.GetConfigurationPath() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/BuildSettings.xml")); + s_DefaultSceneNames.Clear(); + s_SearchScenePaths.Clear(); + + if (!File.Exists(s_ConfigurationPath)) + { + return; + } + + try + { + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.Load(s_ConfigurationPath); + XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework"); + XmlNode xmlBuildSettings = xmlRoot.SelectSingleNode("BuildSettings"); + XmlNode xmlDefaultScenes = xmlBuildSettings.SelectSingleNode("DefaultScenes"); + XmlNode xmlSearchScenePaths = xmlBuildSettings.SelectSingleNode("SearchScenePaths"); + + XmlNodeList xmlNodeList = null; + XmlNode xmlNode = null; + + xmlNodeList = xmlDefaultScenes.ChildNodes; + for (int i = 0; i < xmlNodeList.Count; i++) + { + xmlNode = xmlNodeList.Item(i); + if (xmlNode.Name != "DefaultScene") + { + continue; + } + + string defaultSceneName = xmlNode.Attributes.GetNamedItem("Name").Value; + s_DefaultSceneNames.Add(defaultSceneName); + } + + xmlNodeList = xmlSearchScenePaths.ChildNodes; + for (int i = 0; i < xmlNodeList.Count; i++) + { + xmlNode = xmlNodeList.Item(i); + if (xmlNode.Name != "SearchScenePath") + { + continue; + } + + string searchScenePath = xmlNode.Attributes.GetNamedItem("Path").Value; + s_SearchScenePaths.Add(searchScenePath); + } + } + catch + { + } + } + + /// + /// 将构建场景设置为默认。 + /// + [MenuItem("Game Framework/Scenes in Build Settings/Default Scenes", false, 20)] + public static void DefaultScenes() + { + HashSet sceneNames = new HashSet(); + foreach (string sceneName in s_DefaultSceneNames) + { + sceneNames.Add(sceneName); + } + + List scenes = new List(); + foreach (string sceneName in sceneNames) + { + scenes.Add(new EditorBuildSettingsScene(sceneName, true)); + } + + EditorBuildSettings.scenes = scenes.ToArray(); + + Debug.Log("Set scenes of build settings to default scenes."); + } + + /// + /// 将构建场景设置为所有。 + /// + [MenuItem("Game Framework/Scenes in Build Settings/All Scenes", false, 21)] + public static void AllScenes() + { + HashSet sceneNames = new HashSet(); + foreach (string sceneName in s_DefaultSceneNames) + { + sceneNames.Add(sceneName); + } + + string[] sceneGuids = AssetDatabase.FindAssets("t:Scene", s_SearchScenePaths.ToArray()); + foreach (string sceneGuid in sceneGuids) + { + string sceneName = AssetDatabase.GUIDToAssetPath(sceneGuid); + sceneNames.Add(sceneName); + } + + List scenes = new List(); + foreach (string sceneName in sceneNames) + { + scenes.Add(new EditorBuildSettingsScene(sceneName, true)); + } + + EditorBuildSettings.scenes = scenes.ToArray(); + + Debug.Log("Set scenes of build settings to all scenes."); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettings.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettings.cs.meta new file mode 100644 index 0000000..56fe5ea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b487342e56dd1f649bf6f423bbddd3ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettingsConfigPathAttribute.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettingsConfigPathAttribute.cs new file mode 100644 index 0000000..9da73ec --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettingsConfigPathAttribute.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor +{ + /// + /// BuildSettings 配置路径属性。 + /// + public sealed class BuildSettingsConfigPathAttribute : ConfigPathAttribute + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettingsConfigPathAttribute.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettingsConfigPathAttribute.cs.meta new file mode 100644 index 0000000..51c717d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/BuildSettingsConfigPathAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a40d8263d77546c4391f66bcd3865c5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/ConfigPathAttribute.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/ConfigPathAttribute.cs new file mode 100644 index 0000000..1f2e26f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/ConfigPathAttribute.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace UnityGameFramework.Editor +{ + /// + /// 配置路径属性。 + /// + public abstract class ConfigPathAttribute : Attribute + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/ConfigPathAttribute.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/ConfigPathAttribute.cs.meta new file mode 100644 index 0000000..1e5d8a5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/ConfigPathAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a44584e09310c440b42613540114652 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/Help.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/Help.cs new file mode 100644 index 0000000..89a6fbf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/Help.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor +{ + /// + /// 帮助相关的实用函数。 + /// + public static class Help + { + [MenuItem("Game Framework/Documentation", false, 90)] + public static void ShowDocumentation() + { + ShowHelp("https://gameframework.cn/document/"); + } + + [MenuItem("Game Framework/API Reference", false, 91)] + public static void ShowApiReference() + { + ShowHelp("https://gameframework.cn/api/"); + } + + private static void ShowHelp(string uri) + { + Application.OpenURL(uri); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/Help.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/Help.cs.meta new file mode 100644 index 0000000..4d9ccec --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/Help.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a04b26016cce1146887be6cbb81257a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/HelperInfo.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/HelperInfo.cs new file mode 100644 index 0000000..3200d69 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/HelperInfo.cs @@ -0,0 +1,97 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor +{ + internal sealed class HelperInfo where T : MonoBehaviour + { + private const string CustomOptionName = ""; + + private readonly string m_Name; + + private SerializedProperty m_HelperTypeName; + private SerializedProperty m_CustomHelper; + private string[] m_HelperTypeNames; + private int m_HelperTypeNameIndex; + + public HelperInfo(string name) + { + m_Name = name; + + m_HelperTypeName = null; + m_CustomHelper = null; + m_HelperTypeNames = null; + m_HelperTypeNameIndex = 0; + } + + public void Init(SerializedObject serializedObject) + { + m_HelperTypeName = serializedObject.FindProperty(Utility.Text.Format("m_{0}HelperTypeName", m_Name)); + m_CustomHelper = serializedObject.FindProperty(Utility.Text.Format("m_Custom{0}Helper", m_Name)); + } + + public void Draw() + { + string displayName = FieldNameForDisplay(m_Name); + int selectedIndex = EditorGUILayout.Popup(Utility.Text.Format("{0} Helper", displayName), m_HelperTypeNameIndex, m_HelperTypeNames); + if (selectedIndex != m_HelperTypeNameIndex) + { + m_HelperTypeNameIndex = selectedIndex; + m_HelperTypeName.stringValue = selectedIndex <= 0 ? null : m_HelperTypeNames[selectedIndex]; + } + + if (m_HelperTypeNameIndex <= 0) + { + EditorGUILayout.PropertyField(m_CustomHelper); + if (m_CustomHelper.objectReferenceValue == null) + { + EditorGUILayout.HelpBox(Utility.Text.Format("You must set Custom {0} Helper.", displayName), MessageType.Error); + } + } + } + + public void Refresh() + { + List helperTypeNameList = new List + { + CustomOptionName + }; + + helperTypeNameList.AddRange(Type.GetRuntimeTypeNames(typeof(T))); + m_HelperTypeNames = helperTypeNameList.ToArray(); + + m_HelperTypeNameIndex = 0; + if (!string.IsNullOrEmpty(m_HelperTypeName.stringValue)) + { + m_HelperTypeNameIndex = helperTypeNameList.IndexOf(m_HelperTypeName.stringValue); + if (m_HelperTypeNameIndex <= 0) + { + m_HelperTypeNameIndex = 0; + m_HelperTypeName.stringValue = null; + } + } + } + + private string FieldNameForDisplay(string fieldName) + { + if (string.IsNullOrEmpty(fieldName)) + { + return string.Empty; + } + + string str = Regex.Replace(fieldName, @"^m_", string.Empty); + str = Regex.Replace(str, @"((?<=[a-z])[A-Z]|[A-Z](?=[a-z]))", @" $1").TrimStart(); + return str; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/HelperInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/HelperInfo.cs.meta new file mode 100644 index 0000000..0690695 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/HelperInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ff85bf9d2c44a14d90f78221024499e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/LogRedirection.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/LogRedirection.cs new file mode 100644 index 0000000..5e0323f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/LogRedirection.cs @@ -0,0 +1,122 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +#if !UNITY_2019_1_OR_NEWER + +using System.IO; +using System.Reflection; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEditor.Callbacks; +using UnityEditorInternal; +using UnityEngine; + +namespace UnityGameFramework.Editor +{ + /// + /// 日志重定向相关的实用函数。 + /// + internal static class LogRedirection + { + private static readonly Regex LogRegex = new Regex(@" \(at (.+)\:(\d+)\)\r?\n"); + + [OnOpenAsset(0)] + private static bool OnOpenAsset(int instanceId, int line) + { + string selectedStackTrace = GetSelectedStackTrace(); + if (string.IsNullOrEmpty(selectedStackTrace)) + { + return false; + } + + if (!selectedStackTrace.Contains("UnityGameFramework.Runtime.DefaultLogHelper:Log")) + { + return false; + } + + Match match = LogRegex.Match(selectedStackTrace); + if (!match.Success) + { + return false; + } + + if (!match.Groups[1].Value.Contains("DefaultLogHelper.cs")) + { + return false; + } + + match = match.NextMatch(); + if (!match.Success) + { + return false; + } + + if (match.Groups[1].Value.Contains("GameFrameworkLog.cs")) + { + match = match.NextMatch(); + if (!match.Success) + { + return false; + } + } + + if (match.Groups[1].Value.Contains("Log.cs")) + { + match = match.NextMatch(); + if (!match.Success) + { + return false; + } + } + + InternalEditorUtility.OpenFileAtLineExternal(Path.Combine(Application.dataPath, match.Groups[1].Value.Substring(7)), int.Parse(match.Groups[2].Value)); + return true; + } + + private static string GetSelectedStackTrace() + { + Assembly editorWindowAssembly = typeof(EditorWindow).Assembly; + if (editorWindowAssembly == null) + { + return null; + } + + System.Type consoleWindowType = editorWindowAssembly.GetType("UnityEditor.ConsoleWindow"); + if (consoleWindowType == null) + { + return null; + } + + FieldInfo consoleWindowFieldInfo = consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic); + if (consoleWindowFieldInfo == null) + { + return null; + } + + EditorWindow consoleWindow = consoleWindowFieldInfo.GetValue(null) as EditorWindow; + if (consoleWindow == null) + { + return null; + } + + if (consoleWindow != EditorWindow.focusedWindow) + { + return null; + } + + FieldInfo activeTextFieldInfo = consoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic); + if (activeTextFieldInfo == null) + { + return null; + } + + return (string)activeTextFieldInfo.GetValue(consoleWindow); + } + } +} + +#endif diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/LogRedirection.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/LogRedirection.cs.meta new file mode 100644 index 0000000..4dd64f0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/LogRedirection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb8c486fbd51ec64fab3749895432f7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/LogScriptingDefineSymbols.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/LogScriptingDefineSymbols.cs new file mode 100644 index 0000000..fd2d0fe --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/LogScriptingDefineSymbols.cs @@ -0,0 +1,179 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; + +namespace UnityGameFramework.Editor +{ + /// + /// 日志脚本宏定义。 + /// + public static class LogScriptingDefineSymbols + { + private const string EnableLogScriptingDefineSymbol = "ENABLE_LOG"; + private const string EnableDebugAndAboveLogScriptingDefineSymbol = "ENABLE_DEBUG_AND_ABOVE_LOG"; + private const string EnableInfoAndAboveLogScriptingDefineSymbol = "ENABLE_INFO_AND_ABOVE_LOG"; + private const string EnableWarningAndAboveLogScriptingDefineSymbol = "ENABLE_WARNING_AND_ABOVE_LOG"; + private const string EnableErrorAndAboveLogScriptingDefineSymbol = "ENABLE_ERROR_AND_ABOVE_LOG"; + private const string EnableFatalAndAboveLogScriptingDefineSymbol = "ENABLE_FATAL_AND_ABOVE_LOG"; + private const string EnableDebugLogScriptingDefineSymbol = "ENABLE_DEBUG_LOG"; + private const string EnableInfoLogScriptingDefineSymbol = "ENABLE_INFO_LOG"; + private const string EnableWarningLogScriptingDefineSymbol = "ENABLE_WARNING_LOG"; + private const string EnableErrorLogScriptingDefineSymbol = "ENABLE_ERROR_LOG"; + private const string EnableFatalLogScriptingDefineSymbol = "ENABLE_FATAL_LOG"; + + private static readonly string[] AboveLogScriptingDefineSymbols = new string[] + { + EnableDebugAndAboveLogScriptingDefineSymbol, + EnableInfoAndAboveLogScriptingDefineSymbol, + EnableWarningAndAboveLogScriptingDefineSymbol, + EnableErrorAndAboveLogScriptingDefineSymbol, + EnableFatalAndAboveLogScriptingDefineSymbol + }; + + private static readonly string[] SpecifyLogScriptingDefineSymbols = new string[] + { + EnableDebugLogScriptingDefineSymbol, + EnableInfoLogScriptingDefineSymbol, + EnableWarningLogScriptingDefineSymbol, + EnableErrorLogScriptingDefineSymbol, + EnableFatalLogScriptingDefineSymbol + }; + + /// + /// 禁用所有日志脚本宏定义。 + /// + [MenuItem("Game Framework/Log Scripting Define Symbols/Disable All Logs", false, 30)] + public static void DisableAllLogs() + { + ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableLogScriptingDefineSymbol); + + foreach (string specifyLogScriptingDefineSymbol in SpecifyLogScriptingDefineSymbols) + { + ScriptingDefineSymbols.RemoveScriptingDefineSymbol(specifyLogScriptingDefineSymbol); + } + + foreach (string aboveLogScriptingDefineSymbol in AboveLogScriptingDefineSymbols) + { + ScriptingDefineSymbols.RemoveScriptingDefineSymbol(aboveLogScriptingDefineSymbol); + } + } + + /// + /// 开启所有日志脚本宏定义。 + /// + [MenuItem("Game Framework/Log Scripting Define Symbols/Enable All Logs", false, 31)] + public static void EnableAllLogs() + { + DisableAllLogs(); + ScriptingDefineSymbols.AddScriptingDefineSymbol(EnableLogScriptingDefineSymbol); + } + + /// + /// 开启调试及以上级别的日志脚本宏定义。 + /// + [MenuItem("Game Framework/Log Scripting Define Symbols/Enable Debug And Above Logs", false, 32)] + public static void EnableDebugAndAboveLogs() + { + SetAboveLogScriptingDefineSymbol(EnableDebugAndAboveLogScriptingDefineSymbol); + } + + /// + /// 开启信息及以上级别的日志脚本宏定义。 + /// + [MenuItem("Game Framework/Log Scripting Define Symbols/Enable Info And Above Logs", false, 33)] + public static void EnableInfoAndAboveLogs() + { + SetAboveLogScriptingDefineSymbol(EnableInfoAndAboveLogScriptingDefineSymbol); + } + + /// + /// 开启警告及以上级别的日志脚本宏定义。 + /// + [MenuItem("Game Framework/Log Scripting Define Symbols/Enable Warning And Above Logs", false, 34)] + public static void EnableWarningAndAboveLogs() + { + SetAboveLogScriptingDefineSymbol(EnableWarningAndAboveLogScriptingDefineSymbol); + } + + /// + /// 开启错误及以上级别的日志脚本宏定义。 + /// + [MenuItem("Game Framework/Log Scripting Define Symbols/Enable Error And Above Logs", false, 35)] + public static void EnableErrorAndAboveLogs() + { + SetAboveLogScriptingDefineSymbol(EnableErrorAndAboveLogScriptingDefineSymbol); + } + + /// + /// 开启严重错误及以上级别的日志脚本宏定义。 + /// + [MenuItem("Game Framework/Log Scripting Define Symbols/Enable Fatal And Above Logs", false, 36)] + public static void EnableFatalAndAboveLogs() + { + SetAboveLogScriptingDefineSymbol(EnableFatalAndAboveLogScriptingDefineSymbol); + } + + /// + /// 设置日志脚本宏定义。 + /// + /// 要设置的日志脚本宏定义。 + public static void SetAboveLogScriptingDefineSymbol(string aboveLogScriptingDefineSymbol) + { + if (string.IsNullOrEmpty(aboveLogScriptingDefineSymbol)) + { + return; + } + + foreach (string i in AboveLogScriptingDefineSymbols) + { + if (i == aboveLogScriptingDefineSymbol) + { + DisableAllLogs(); + ScriptingDefineSymbols.AddScriptingDefineSymbol(aboveLogScriptingDefineSymbol); + return; + } + } + } + + /// + /// 设置日志脚本宏定义。 + /// + /// 要设置的日志脚本宏定义。 + public static void SetSpecifyLogScriptingDefineSymbols(string[] specifyLogScriptingDefineSymbols) + { + if (specifyLogScriptingDefineSymbols == null || specifyLogScriptingDefineSymbols.Length <= 0) + { + return; + } + + bool removed = false; + foreach (string specifyLogScriptingDefineSymbol in specifyLogScriptingDefineSymbols) + { + if (string.IsNullOrEmpty(specifyLogScriptingDefineSymbol)) + { + continue; + } + + foreach (string i in SpecifyLogScriptingDefineSymbols) + { + if (i == specifyLogScriptingDefineSymbol) + { + if (!removed) + { + removed = true; + DisableAllLogs(); + } + + ScriptingDefineSymbols.AddScriptingDefineSymbol(specifyLogScriptingDefineSymbol); + break; + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/LogScriptingDefineSymbols.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/LogScriptingDefineSymbols.cs.meta new file mode 100644 index 0000000..46c0c6c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/LogScriptingDefineSymbols.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b5eed5f56efa7e4cb245bee9b064c21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/OpenFolder.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/OpenFolder.cs new file mode 100644 index 0000000..78ce52b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/OpenFolder.cs @@ -0,0 +1,91 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Diagnostics; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor +{ + /// + /// 打开文件夹相关的实用函数。 + /// + public static class OpenFolder + { + /// + /// 打开 Data Path 文件夹。 + /// + [MenuItem("Game Framework/Open Folder/Data Path", false, 10)] + public static void OpenFolderDataPath() + { + Execute(Application.dataPath); + } + + /// + /// 打开 Persistent Data Path 文件夹。 + /// + [MenuItem("Game Framework/Open Folder/Persistent Data Path", false, 11)] + public static void OpenFolderPersistentDataPath() + { + Execute(Application.persistentDataPath); + } + + /// + /// 打开 Streaming Assets Path 文件夹。 + /// + [MenuItem("Game Framework/Open Folder/Streaming Assets Path", false, 12)] + public static void OpenFolderStreamingAssetsPath() + { + Execute(Application.streamingAssetsPath); + } + + /// + /// 打开 Temporary Cache Path 文件夹。 + /// + [MenuItem("Game Framework/Open Folder/Temporary Cache Path", false, 13)] + public static void OpenFolderTemporaryCachePath() + { + Execute(Application.temporaryCachePath); + } + +#if UNITY_2018_3_OR_NEWER + + /// + /// 打开 Console Log Path 文件夹。 + /// + [MenuItem("Game Framework/Open Folder/Console Log Path", false, 14)] + public static void OpenFolderConsoleLogPath() + { + Execute(System.IO.Path.GetDirectoryName(Application.consoleLogPath)); + } + +#endif + + /// + /// 打开指定路径的文件夹。 + /// + /// 要打开的文件夹的路径。 + public static void Execute(string folder) + { + folder = Utility.Text.Format("\"{0}\"", folder); + switch (Application.platform) + { + case RuntimePlatform.WindowsEditor: + Process.Start("Explorer.exe", folder.Replace('/', '\\')); + break; + + case RuntimePlatform.OSXEditor: + Process.Start("open", folder); + break; + + default: + throw new GameFrameworkException(Utility.Text.Format("Not support open folder on '{0}' platform.", Application.platform)); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/OpenFolder.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/OpenFolder.cs.meta new file mode 100644 index 0000000..e948d83 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/OpenFolder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62e84f6e8237ea540b348d07a13891c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/ScriptingDefineSymbols.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/ScriptingDefineSymbols.cs new file mode 100644 index 0000000..5e05418 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/ScriptingDefineSymbols.cs @@ -0,0 +1,157 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; +using UnityEditor; + +namespace UnityGameFramework.Editor +{ + /// + /// 脚本宏定义。 + /// + public static class ScriptingDefineSymbols + { + private static readonly BuildTargetGroup[] BuildTargetGroups = new BuildTargetGroup[] + { + BuildTargetGroup.Standalone, + BuildTargetGroup.iOS, + BuildTargetGroup.Android, + BuildTargetGroup.WSA, + BuildTargetGroup.WebGL + }; + + /// + /// 检查指定平台是否存在指定的脚本宏定义。 + /// + /// 要检查脚本宏定义的平台。 + /// 要检查的脚本宏定义。 + /// 指定平台是否存在指定的脚本宏定义。 + public static bool HasScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol) + { + if (string.IsNullOrEmpty(scriptingDefineSymbol)) + { + return false; + } + + string[] scriptingDefineSymbols = GetScriptingDefineSymbols(buildTargetGroup); + foreach (string i in scriptingDefineSymbols) + { + if (i == scriptingDefineSymbol) + { + return true; + } + } + + return false; + } + + /// + /// 为指定平台增加指定的脚本宏定义。 + /// + /// 要增加脚本宏定义的平台。 + /// 要增加的脚本宏定义。 + public static void AddScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol) + { + if (string.IsNullOrEmpty(scriptingDefineSymbol)) + { + return; + } + + if (HasScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol)) + { + return; + } + + List scriptingDefineSymbols = new List(GetScriptingDefineSymbols(buildTargetGroup)) + { + scriptingDefineSymbol + }; + + SetScriptingDefineSymbols(buildTargetGroup, scriptingDefineSymbols.ToArray()); + } + + /// + /// 为指定平台移除指定的脚本宏定义。 + /// + /// 要移除脚本宏定义的平台。 + /// 要移除的脚本宏定义。 + public static void RemoveScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol) + { + if (string.IsNullOrEmpty(scriptingDefineSymbol)) + { + return; + } + + if (!HasScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol)) + { + return; + } + + List scriptingDefineSymbols = new List(GetScriptingDefineSymbols(buildTargetGroup)); + while (scriptingDefineSymbols.Contains(scriptingDefineSymbol)) + { + scriptingDefineSymbols.Remove(scriptingDefineSymbol); + } + + SetScriptingDefineSymbols(buildTargetGroup, scriptingDefineSymbols.ToArray()); + } + + /// + /// 为所有平台增加指定的脚本宏定义。 + /// + /// 要增加的脚本宏定义。 + public static void AddScriptingDefineSymbol(string scriptingDefineSymbol) + { + if (string.IsNullOrEmpty(scriptingDefineSymbol)) + { + return; + } + + foreach (BuildTargetGroup buildTargetGroup in BuildTargetGroups) + { + AddScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol); + } + } + + /// + /// 为所有平台移除指定的脚本宏定义。 + /// + /// 要移除的脚本宏定义。 + public static void RemoveScriptingDefineSymbol(string scriptingDefineSymbol) + { + if (string.IsNullOrEmpty(scriptingDefineSymbol)) + { + return; + } + + foreach (BuildTargetGroup buildTargetGroup in BuildTargetGroups) + { + RemoveScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol); + } + } + + /// + /// 获取指定平台的脚本宏定义。 + /// + /// 要获取脚本宏定义的平台。 + /// 平台的脚本宏定义。 + public static string[] GetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup) + { + return PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';'); + } + + /// + /// 设置指定平台的脚本宏定义。 + /// + /// 要设置脚本宏定义的平台。 + /// 要设置的脚本宏定义。 + public static void SetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup, string[] scriptingDefineSymbols) + { + PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", scriptingDefineSymbols)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/ScriptingDefineSymbols.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/ScriptingDefineSymbols.cs.meta new file mode 100644 index 0000000..a7eca4a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/ScriptingDefineSymbols.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99eaa7f830bac2c469f9aab52406b8ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/Type.cs b/Packages/com.bywaystudios.gameframework/Editor/Misc/Type.cs new file mode 100644 index 0000000..1cb34d1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/Type.cs @@ -0,0 +1,127 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using System.Reflection; + +namespace UnityGameFramework.Editor +{ + /// + /// 类型相关的实用函数。 + /// + internal static class Type + { + private static readonly string[] RuntimeAssemblyNames = + { +#if UNITY_2017_3_OR_NEWER + "UnityGameFramework.Runtime", +#endif + "Assembly-CSharp", + }; + + private static readonly string[] RuntimeOrEditorAssemblyNames = + { +#if UNITY_2017_3_OR_NEWER + "UnityGameFramework.Runtime", +#endif + "Assembly-CSharp", +#if UNITY_2017_3_OR_NEWER + "UnityGameFramework.Editor", +#endif + "Assembly-CSharp-Editor", + }; + + /// + /// 获取配置路径。 + /// + /// 配置类型。 + /// 配置路径。 + internal static string GetConfigurationPath() where T : ConfigPathAttribute + { + foreach (System.Type type in Utility.Assembly.GetTypes()) + { + if (!type.IsAbstract || !type.IsSealed) + { + continue; + } + + foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) + { + if (fieldInfo.FieldType == typeof(string) && fieldInfo.IsDefined(typeof(T), false)) + { + return (string)fieldInfo.GetValue(null); + } + } + + foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) + { + if (propertyInfo.PropertyType == typeof(string) && propertyInfo.IsDefined(typeof(T), false)) + { + return (string)propertyInfo.GetValue(null, null); + } + } + } + + return null; + } + + /// + /// 在运行时程序集中获取指定基类的所有子类的名称。 + /// + /// 基类类型。 + /// 指定基类的所有子类的名称。 + internal static string[] GetRuntimeTypeNames(System.Type typeBase) + { + return GetTypeNames(typeBase, RuntimeAssemblyNames); + } + + /// + /// 在运行时或编辑器程序集中获取指定基类的所有子类的名称。 + /// + /// 基类类型。 + /// 指定基类的所有子类的名称。 + internal static string[] GetRuntimeOrEditorTypeNames(System.Type typeBase) + { + return GetTypeNames(typeBase, RuntimeOrEditorAssemblyNames); + } + + private static string[] GetTypeNames(System.Type typeBase, string[] assemblyNames) + { + List typeNames = new List(); + foreach (string assemblyName in assemblyNames) + { + Assembly assembly = null; + try + { + assembly = Assembly.Load(assemblyName); + } + catch + { + continue; + } + + if (assembly == null) + { + continue; + } + + System.Type[] types = assembly.GetTypes(); + foreach (System.Type type in types) + { + if (type.IsClass && !type.IsAbstract && typeBase.IsAssignableFrom(type)) + { + typeNames.Add(type.FullName); + } + } + } + + typeNames.Sort(); + return typeNames.ToArray(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/Misc/Type.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/Misc/Type.cs.meta new file mode 100644 index 0000000..8064749 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/Misc/Type.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82f73088e6e538649abbb7e35e3d6bf5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer.meta new file mode 100644 index 0000000..3090394 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fd9595fe20f16b6418ee574335afadca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/AssetsOrder.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/AssetsOrder.cs new file mode 100644 index 0000000..7914d97 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/AssetsOrder.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + public enum AssetsOrder : byte + { + AssetNameAsc, + AssetNameDesc, + DependencyResourceCountAsc, + DependencyResourceCountDesc, + DependencyAssetCountAsc, + DependencyAssetCountDesc, + ScatteredDependencyAssetCountAsc, + ScatteredDependencyAssetCountDesc, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/AssetsOrder.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/AssetsOrder.cs.meta new file mode 100644 index 0000000..22c68b5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/AssetsOrder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53e74863b20de0742bad85898d617db6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/DependencyData.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/DependencyData.cs new file mode 100644 index 0000000..a4e77a3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/DependencyData.cs @@ -0,0 +1,96 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed class DependencyData + { + private List m_DependencyResources; + private List m_DependencyAssets; + private List m_ScatteredDependencyAssetNames; + + public DependencyData() + { + m_DependencyResources = new List(); + m_DependencyAssets = new List(); + m_ScatteredDependencyAssetNames = new List(); + } + + public int DependencyResourceCount + { + get + { + return m_DependencyResources.Count; + } + } + + public int DependencyAssetCount + { + get + { + return m_DependencyAssets.Count; + } + } + + public int ScatteredDependencyAssetCount + { + get + { + return m_ScatteredDependencyAssetNames.Count; + } + } + + public void AddDependencyAsset(Asset asset) + { + if (!m_DependencyResources.Contains(asset.Resource)) + { + m_DependencyResources.Add(asset.Resource); + } + + m_DependencyAssets.Add(asset); + } + + public void AddScatteredDependencyAsset(string dependencyAssetName) + { + m_ScatteredDependencyAssetNames.Add(dependencyAssetName); + } + + public Resource[] GetDependencyResources() + { + return m_DependencyResources.ToArray(); + } + + public Asset[] GetDependencyAssets() + { + return m_DependencyAssets.ToArray(); + } + + public string[] GetScatteredDependencyAssetNames() + { + return m_ScatteredDependencyAssetNames.ToArray(); + } + + public void RefreshData() + { + m_DependencyResources.Sort(DependencyResourcesComparer); + m_DependencyAssets.Sort(DependencyAssetsComparer); + m_ScatteredDependencyAssetNames.Sort(); + } + + private int DependencyResourcesComparer(Resource a, Resource b) + { + return a.FullName.CompareTo(b.FullName); + } + + private int DependencyAssetsComparer(Asset a, Asset b) + { + return a.Name.CompareTo(b.Name); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/DependencyData.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/DependencyData.cs.meta new file mode 100644 index 0000000..6a1408c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/DependencyData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 325edc30663628f4a917226eeee0b733 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzer.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzer.cs new file mode 100644 index 0000000..7401692 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzer.cs @@ -0,0 +1,533 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源分析器。 + /// + internal sealed class ResourceAnalyzer : EditorWindow + { + private ResourceAnalyzerController m_Controller = null; + private bool m_Analyzed = false; + private int m_ToolbarIndex = 0; + + private int m_AssetCount = 0; + private string[] m_CachedAssetNames = null; + private int m_SelectedAssetIndex = -1; + private string m_SelectedAssetName = null; + private DependencyData m_SelectedDependencyData = null; + private AssetsOrder m_AssetsOrder = AssetsOrder.AssetNameAsc; + private string m_AssetsFilter = null; + private Vector2 m_AssetsScroll = Vector2.zero; + private Vector2 m_DependencyResourcesScroll = Vector2.zero; + private Vector2 m_DependencyAssetsScroll = Vector2.zero; + private Vector2 m_ScatteredDependencyAssetsScroll = Vector2.zero; + + private int m_ScatteredAssetCount = 0; + private string[] m_CachedScatteredAssetNames = null; + private int m_SelectedScatteredAssetIndex = -1; + private string m_SelectedScatteredAssetName = null; + private Asset[] m_SelectedHostAssets = null; + private ScatteredAssetsOrder m_ScatteredAssetsOrder = ScatteredAssetsOrder.AssetNameAsc; + private string m_ScatteredAssetsFilter = null; + private Vector2 m_ScatteredAssetsScroll = Vector2.zero; + private Vector2 m_HostAssetsScroll = Vector2.zero; + + private int m_CircularDependencyCount = 0; + private string[][] m_CachedCircularDependencyDatas = null; + private Vector2 m_CircularDependencyScroll = Vector2.zero; + + [MenuItem("Game Framework/Resource Tools/Resource Analyzer", false, 42)] + private static void Open() + { + ResourceAnalyzer window = GetWindow("Resource Analyzer", true); + window.minSize = new Vector2(800f, 600f); + } + + private void OnEnable() + { + m_Controller = new ResourceAnalyzerController(); + m_Controller.OnLoadingResource += OnLoadingResource; + m_Controller.OnLoadingAsset += OnLoadingAsset; + m_Controller.OnLoadCompleted += OnLoadCompleted; + m_Controller.OnAnalyzingAsset += OnAnalyzingAsset; + m_Controller.OnAnalyzeCompleted += OnAnalyzeCompleted; + + m_Analyzed = false; + m_ToolbarIndex = 0; + + m_AssetCount = 0; + m_CachedAssetNames = null; + m_SelectedAssetIndex = -1; + m_SelectedAssetName = null; + m_SelectedDependencyData = new DependencyData(); + m_AssetsOrder = AssetsOrder.ScatteredDependencyAssetCountDesc; + m_AssetsFilter = null; + m_AssetsScroll = Vector2.zero; + m_DependencyResourcesScroll = Vector2.zero; + m_DependencyAssetsScroll = Vector2.zero; + m_ScatteredDependencyAssetsScroll = Vector2.zero; + + m_ScatteredAssetCount = 0; + m_CachedScatteredAssetNames = null; + m_SelectedScatteredAssetIndex = -1; + m_SelectedScatteredAssetName = null; + m_SelectedHostAssets = new Asset[] { }; + m_ScatteredAssetsOrder = ScatteredAssetsOrder.HostAssetCountDesc; + m_ScatteredAssetsFilter = null; + m_ScatteredAssetsScroll = Vector2.zero; + m_HostAssetsScroll = Vector2.zero; + + m_CircularDependencyCount = 0; + m_CachedCircularDependencyDatas = null; + m_CircularDependencyScroll = Vector2.zero; + } + + private void OnGUI() + { + EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height)); + { + GUILayout.Space(5f); + int toolbarIndex = GUILayout.Toolbar(m_ToolbarIndex, new string[] { "Summary", "Asset Dependency Viewer", "Scattered Asset Viewer", "Circular Dependency Viewer" }, GUILayout.Height(30f)); + if (toolbarIndex != m_ToolbarIndex) + { + m_ToolbarIndex = toolbarIndex; + GUI.FocusControl(null); + } + + switch (m_ToolbarIndex) + { + case 0: + DrawSummary(); + break; + + case 1: + DrawAssetDependencyViewer(); + break; + + case 2: + DrawScatteredAssetViewer(); + break; + + case 3: + DrawCircularDependencyViewer(); + break; + } + } + EditorGUILayout.EndVertical(); + } + + private void DrawAnalyzeButton() + { + if (!m_Analyzed) + { + EditorGUILayout.HelpBox("Please analyze first.", MessageType.Info); + } + + if (GUILayout.Button("Analyze", GUILayout.Height(30f))) + { + m_Controller.Clear(); + + m_SelectedAssetIndex = -1; + m_SelectedAssetName = null; + m_SelectedDependencyData = new DependencyData(); + + m_SelectedScatteredAssetIndex = -1; + m_SelectedScatteredAssetName = null; + m_SelectedHostAssets = new Asset[] { }; + + if (m_Controller.Prepare()) + { + m_Controller.Analyze(); + m_Analyzed = true; + m_AssetCount = m_Controller.GetAssetNames().Length; + m_ScatteredAssetCount = m_Controller.GetScatteredAssetNames().Length; + m_CachedCircularDependencyDatas = m_Controller.GetCircularDependencyDatas(); + m_CircularDependencyCount = m_CachedCircularDependencyDatas.Length; + OnAssetsOrderOrFilterChanged(); + OnScatteredAssetsOrderOrFilterChanged(); + } + else + { + EditorUtility.DisplayDialog("Resource Analyze", "Can not parse 'ResourceCollection.xml', please use 'Resource Editor' tool first.", "OK"); + } + } + } + + private void DrawSummary() + { + DrawAnalyzeButton(); + } + + private void DrawAssetDependencyViewer() + { + if (!m_Analyzed) + { + DrawAnalyzeButton(); + return; + } + + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Space(5f); + EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.4f)); + { + GUILayout.Space(5f); + string title = null; + if (string.IsNullOrEmpty(m_AssetsFilter)) + { + title = Utility.Text.Format("Assets In Resources ({0})", m_AssetCount); + } + else + { + title = Utility.Text.Format("Assets In Resources ({0}/{1})", m_CachedAssetNames.Length, m_AssetCount); + } + EditorGUILayout.LabelField(title, EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 150f)); + { + m_AssetsScroll = EditorGUILayout.BeginScrollView(m_AssetsScroll); + { + int selectedIndex = GUILayout.SelectionGrid(m_SelectedAssetIndex, m_CachedAssetNames, 1, "toggle"); + if (selectedIndex != m_SelectedAssetIndex) + { + m_SelectedAssetIndex = selectedIndex; + m_SelectedAssetName = m_CachedAssetNames[selectedIndex]; + m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName); + } + } + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.LabelField("Asset Name", m_SelectedAssetName ?? ""); + EditorGUILayout.LabelField("Resource Name", m_SelectedAssetName == null ? "" : m_Controller.GetAsset(m_SelectedAssetName).Resource.FullName); + EditorGUILayout.BeginHorizontal(); + { + AssetsOrder assetsOrder = (AssetsOrder)EditorGUILayout.EnumPopup("Order by", m_AssetsOrder); + if (assetsOrder != m_AssetsOrder) + { + m_AssetsOrder = assetsOrder; + OnAssetsOrderOrFilterChanged(); + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + string assetsFilter = EditorGUILayout.TextField("Assets Filter", m_AssetsFilter); + if (assetsFilter != m_AssetsFilter) + { + m_AssetsFilter = assetsFilter; + OnAssetsOrderOrFilterChanged(); + } + EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_AssetsFilter)); + { + if (GUILayout.Button("x", GUILayout.Width(20f))) + { + m_AssetsFilter = null; + GUI.FocusControl(null); + OnAssetsOrderOrFilterChanged(); + } + } + EditorGUI.EndDisabledGroup(); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.6f - 14f)); + { + GUILayout.Space(5f); + EditorGUILayout.LabelField(Utility.Text.Format("Dependency Resources ({0})", m_SelectedDependencyData.DependencyResourceCount), EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.2f)); + { + m_DependencyResourcesScroll = EditorGUILayout.BeginScrollView(m_DependencyResourcesScroll); + { + Resource[] dependencyResources = m_SelectedDependencyData.GetDependencyResources(); + foreach (Resource dependencyResource in dependencyResources) + { + GUILayout.Label(dependencyResource.FullName); + } + } + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.LabelField(Utility.Text.Format("Dependency Assets ({0})", m_SelectedDependencyData.DependencyAssetCount), EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.3f)); + { + m_DependencyAssetsScroll = EditorGUILayout.BeginScrollView(m_DependencyAssetsScroll); + { + Asset[] dependencyAssets = m_SelectedDependencyData.GetDependencyAssets(); + foreach (Asset dependencyAsset in dependencyAssets) + { + EditorGUILayout.BeginHorizontal(); + { + if (GUILayout.Button("GO", GUILayout.Width(30f))) + { + m_SelectedAssetName = dependencyAsset.Name; + m_SelectedAssetIndex = new List(m_CachedAssetNames).IndexOf(m_SelectedAssetName); + m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName); + } + + GUILayout.Label(dependencyAsset.Name); + } + EditorGUILayout.EndHorizontal(); + } + } + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.LabelField(Utility.Text.Format("Scattered Dependency Assets ({0})", m_SelectedDependencyData.ScatteredDependencyAssetCount), EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.5f - 116f)); + { + m_ScatteredDependencyAssetsScroll = EditorGUILayout.BeginScrollView(m_ScatteredDependencyAssetsScroll); + { + string[] scatteredDependencyAssetNames = m_SelectedDependencyData.GetScatteredDependencyAssetNames(); + foreach (string scatteredDependencyAssetName in scatteredDependencyAssetNames) + { + EditorGUILayout.BeginHorizontal(); + { + int count = m_Controller.GetHostAssets(scatteredDependencyAssetName).Length; + EditorGUI.BeginDisabledGroup(count < 2); + { + if (GUILayout.Button("GO", GUILayout.Width(30f))) + { + m_SelectedScatteredAssetName = scatteredDependencyAssetName; + m_SelectedScatteredAssetIndex = new List(m_CachedScatteredAssetNames).IndexOf(m_SelectedScatteredAssetName); + m_SelectedHostAssets = m_Controller.GetHostAssets(m_SelectedScatteredAssetName); + m_ToolbarIndex = 2; + GUI.FocusControl(null); + } + } + EditorGUI.EndDisabledGroup(); + GUILayout.Label(count > 1 ? Utility.Text.Format("{0} ({1})", scatteredDependencyAssetName, count) : scatteredDependencyAssetName); + } + EditorGUILayout.EndHorizontal(); + } + } + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndHorizontal(); + } + + private void DrawScatteredAssetViewer() + { + if (!m_Analyzed) + { + DrawAnalyzeButton(); + return; + } + + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Space(5f); + EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.4f)); + { + GUILayout.Space(5f); + string title = null; + if (string.IsNullOrEmpty(m_ScatteredAssetsFilter)) + { + title = Utility.Text.Format("Scattered Assets ({0})", m_ScatteredAssetCount); + } + else + { + title = Utility.Text.Format("Scattered Assets ({0}/{1})", m_CachedScatteredAssetNames.Length, m_ScatteredAssetCount); + } + EditorGUILayout.LabelField(title, EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 132f)); + { + m_ScatteredAssetsScroll = EditorGUILayout.BeginScrollView(m_ScatteredAssetsScroll); + { + int selectedIndex = GUILayout.SelectionGrid(m_SelectedScatteredAssetIndex, m_CachedScatteredAssetNames, 1, "toggle"); + if (selectedIndex != m_SelectedScatteredAssetIndex) + { + m_SelectedScatteredAssetIndex = selectedIndex; + m_SelectedScatteredAssetName = m_CachedScatteredAssetNames[selectedIndex]; + m_SelectedHostAssets = m_Controller.GetHostAssets(m_SelectedScatteredAssetName); + } + } + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.LabelField("Scattered Asset Name", m_SelectedScatteredAssetName ?? ""); + EditorGUILayout.BeginHorizontal(); + { + ScatteredAssetsOrder scatteredAssetsOrder = (ScatteredAssetsOrder)EditorGUILayout.EnumPopup("Order by", m_ScatteredAssetsOrder); + if (scatteredAssetsOrder != m_ScatteredAssetsOrder) + { + m_ScatteredAssetsOrder = scatteredAssetsOrder; + OnScatteredAssetsOrderOrFilterChanged(); + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + string scatteredAssetsFilter = EditorGUILayout.TextField("Assets Filter", m_ScatteredAssetsFilter); + if (scatteredAssetsFilter != m_ScatteredAssetsFilter) + { + m_ScatteredAssetsFilter = scatteredAssetsFilter; + OnScatteredAssetsOrderOrFilterChanged(); + } + EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_ScatteredAssetsFilter)); + { + if (GUILayout.Button("x", GUILayout.Width(20f))) + { + m_ScatteredAssetsFilter = null; + GUI.FocusControl(null); + OnScatteredAssetsOrderOrFilterChanged(); + } + } + EditorGUI.EndDisabledGroup(); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.6f - 14f)); + { + GUILayout.Space(5f); + EditorGUILayout.LabelField(Utility.Text.Format("Host Assets ({0})", m_SelectedHostAssets.Length), EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 68f)); + { + m_HostAssetsScroll = EditorGUILayout.BeginScrollView(m_HostAssetsScroll); + { + foreach (Asset hostAsset in m_SelectedHostAssets) + { + EditorGUILayout.BeginHorizontal(); + { + if (GUILayout.Button("GO", GUILayout.Width(30f))) + { + m_SelectedAssetName = hostAsset.Name; + m_SelectedAssetIndex = new List(m_CachedAssetNames).IndexOf(m_SelectedAssetName); + m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName); + m_ToolbarIndex = 1; + GUI.FocusControl(null); + } + + GUILayout.Label(Utility.Text.Format("{0} [{1}]", hostAsset.Name, hostAsset.Resource.FullName)); + } + EditorGUILayout.EndHorizontal(); + } + } + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndHorizontal(); + } + + private void DrawCircularDependencyViewer() + { + if (!m_Analyzed) + { + DrawAnalyzeButton(); + return; + } + + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Space(5f); + EditorGUILayout.BeginVertical(); + { + GUILayout.Space(5f); + EditorGUILayout.LabelField(Utility.Text.Format("Circular Dependency ({0})", m_CircularDependencyCount), EditorStyles.boldLabel); + m_CircularDependencyScroll = EditorGUILayout.BeginScrollView(m_CircularDependencyScroll); + { + int count = 0; + foreach (string[] circularDependencyData in m_CachedCircularDependencyDatas) + { + GUILayout.Label(Utility.Text.Format("{0}) {1}", ++count, circularDependencyData[circularDependencyData.Length - 1]), EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box"); + { + foreach (string circularDependency in circularDependencyData) + { + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Label(circularDependency); + if (GUILayout.Button("GO", GUILayout.Width(30f))) + { + m_SelectedAssetName = circularDependency; + m_SelectedAssetIndex = new List(m_CachedAssetNames).IndexOf(m_SelectedAssetName); + m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName); + m_ToolbarIndex = 1; + GUI.FocusControl(null); + } + } + EditorGUILayout.EndHorizontal(); + } + } + EditorGUILayout.EndVertical(); + GUILayout.Space(5f); + } + } + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndHorizontal(); + } + + private void OnAssetsOrderOrFilterChanged() + { + m_CachedAssetNames = m_Controller.GetAssetNames(m_AssetsOrder, m_AssetsFilter); + if (!string.IsNullOrEmpty(m_SelectedAssetName)) + { + m_SelectedAssetIndex = new List(m_CachedAssetNames).IndexOf(m_SelectedAssetName); + } + } + + private void OnScatteredAssetsOrderOrFilterChanged() + { + m_CachedScatteredAssetNames = m_Controller.GetScatteredAssetNames(m_ScatteredAssetsOrder, m_ScatteredAssetsFilter); + if (!string.IsNullOrEmpty(m_SelectedScatteredAssetName)) + { + m_SelectedScatteredAssetIndex = new List(m_CachedScatteredAssetNames).IndexOf(m_SelectedScatteredAssetName); + } + } + + private void OnLoadingResource(int index, int count) + { + EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index, count), (float)index / count); + } + + private void OnLoadingAsset(int index, int count) + { + EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index, count), (float)index / count); + } + + private void OnLoadCompleted() + { + EditorUtility.ClearProgressBar(); + } + + private void OnAnalyzingAsset(int index, int count) + { + EditorUtility.DisplayProgressBar("Analyzing Assets", Utility.Text.Format("Analyzing assets, {0}/{1} analyzed.", index, count), (float)index / count); + } + + private void OnAnalyzeCompleted() + { + EditorUtility.ClearProgressBar(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzer.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzer.cs.meta new file mode 100644 index 0000000..0d35147 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e7971f49bcdc654fb34a9fdaa2a6d29 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.CircularDependencyChecker.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.CircularDependencyChecker.cs new file mode 100644 index 0000000..4732179 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.CircularDependencyChecker.cs @@ -0,0 +1,76 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; +using System.Linq; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceAnalyzerController + { + private sealed class CircularDependencyChecker + { + private readonly Stamp[] m_Stamps; + + public CircularDependencyChecker(Stamp[] stamps) + { + m_Stamps = stamps; + } + + public string[][] Check() + { + HashSet hosts = new HashSet(); + foreach (Stamp stamp in m_Stamps) + { + hosts.Add(stamp.HostAssetName); + } + + List results = new List(); + foreach (string host in hosts) + { + LinkedList route = new LinkedList(); + HashSet visited = new HashSet(); + if (Check(host, route, visited)) + { + results.Add(route.ToArray()); + } + } + + return results.ToArray(); + } + + private bool Check(string host, LinkedList route, HashSet visited) + { + visited.Add(host); + route.AddLast(host); + + foreach (Stamp stamp in m_Stamps) + { + if (host != stamp.HostAssetName) + { + continue; + } + + if (visited.Contains(stamp.DependencyAssetName)) + { + route.AddLast(stamp.DependencyAssetName); + return true; + } + + if (Check(stamp.DependencyAssetName, route, visited)) + { + return true; + } + } + + route.RemoveLast(); + visited.Remove(host); + return false; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.CircularDependencyChecker.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.CircularDependencyChecker.cs.meta new file mode 100644 index 0000000..561557b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.CircularDependencyChecker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97329d75bce6b634282bf05ff3453fba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.Stamp.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.Stamp.cs new file mode 100644 index 0000000..c964cbd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.Stamp.cs @@ -0,0 +1,43 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceAnalyzerController + { + [StructLayout(LayoutKind.Auto)] + private struct Stamp + { + private readonly string m_HostAssetName; + private readonly string m_DependencyAssetName; + + public Stamp(string hostAssetName, string dependencyAssetName) + { + m_HostAssetName = hostAssetName; + m_DependencyAssetName = dependencyAssetName; + } + + public string HostAssetName + { + get + { + return m_HostAssetName; + } + } + + public string DependencyAssetName + { + get + { + return m_DependencyAssetName; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.Stamp.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.Stamp.cs.meta new file mode 100644 index 0000000..ad6ddac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.Stamp.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15cf99f0cd968de4e876c49401fa5294 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.cs new file mode 100644 index 0000000..60f512f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.cs @@ -0,0 +1,324 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceAnalyzerController + { + private readonly ResourceCollection m_ResourceCollection; + + private readonly Dictionary m_DependencyDatas; + private readonly Dictionary> m_ScatteredAssets; + private readonly List m_CircularDependencyDatas; + private readonly HashSet m_AnalyzedStamps; + + public ResourceAnalyzerController() + : this(null) + { + } + + public ResourceAnalyzerController(ResourceCollection resourceCollection) + { + m_ResourceCollection = resourceCollection != null ? resourceCollection : new ResourceCollection(); + + m_ResourceCollection.OnLoadingResource += delegate (int index, int count) + { + if (OnLoadingResource != null) + { + OnLoadingResource(index, count); + } + }; + + m_ResourceCollection.OnLoadingAsset += delegate (int index, int count) + { + if (OnLoadingAsset != null) + { + OnLoadingAsset(index, count); + } + }; + + m_ResourceCollection.OnLoadCompleted += delegate () + { + if (OnLoadCompleted != null) + { + OnLoadCompleted(); + } + }; + + m_DependencyDatas = new Dictionary(StringComparer.Ordinal); + m_ScatteredAssets = new Dictionary>(StringComparer.Ordinal); + m_AnalyzedStamps = new HashSet(); + m_CircularDependencyDatas = new List(); + } + + public event GameFrameworkAction OnLoadingResource = null; + + public event GameFrameworkAction OnLoadingAsset = null; + + public event GameFrameworkAction OnLoadCompleted = null; + + public event GameFrameworkAction OnAnalyzingAsset = null; + + public event GameFrameworkAction OnAnalyzeCompleted = null; + + public void Clear() + { + m_ResourceCollection.Clear(); + m_DependencyDatas.Clear(); + m_ScatteredAssets.Clear(); + m_CircularDependencyDatas.Clear(); + m_AnalyzedStamps.Clear(); + } + + public bool Prepare() + { + m_ResourceCollection.Clear(); + return m_ResourceCollection.Load(); + } + + public void Analyze() + { + m_DependencyDatas.Clear(); + m_ScatteredAssets.Clear(); + m_CircularDependencyDatas.Clear(); + m_AnalyzedStamps.Clear(); + + HashSet scriptAssetNames = GetFilteredAssetNames("t:Script"); + Asset[] assets = m_ResourceCollection.GetAssets(); + int count = assets.Length; + for (int i = 0; i < count; i++) + { + if (OnAnalyzingAsset != null) + { + OnAnalyzingAsset(i, count); + } + + string assetName = assets[i].Name; + if (string.IsNullOrEmpty(assetName)) + { + Debug.LogWarning(Utility.Text.Format("Can not find asset by guid '{0}'.", assets[i].Guid)); + continue; + } + + DependencyData dependencyData = new DependencyData(); + AnalyzeAsset(assetName, assets[i], dependencyData, scriptAssetNames); + dependencyData.RefreshData(); + m_DependencyDatas.Add(assetName, dependencyData); + } + + foreach (List scatteredAsset in m_ScatteredAssets.Values) + { + scatteredAsset.Sort((a, b) => a.Name.CompareTo(b.Name)); + } + + m_CircularDependencyDatas.AddRange(new CircularDependencyChecker(m_AnalyzedStamps.ToArray()).Check()); + + if (OnAnalyzeCompleted != null) + { + OnAnalyzeCompleted(); + } + } + + private void AnalyzeAsset(string assetName, Asset hostAsset, DependencyData dependencyData, HashSet scriptAssetNames) + { + string[] dependencyAssetNames = AssetDatabase.GetDependencies(assetName, false); + foreach (string dependencyAssetName in dependencyAssetNames) + { + if (scriptAssetNames.Contains(dependencyAssetName)) + { + continue; + } + + if (dependencyAssetName == assetName) + { + continue; + } + + if (dependencyAssetName.EndsWith(".unity", StringComparison.Ordinal)) + { + // 忽略对场景的依赖 + continue; + } + + Stamp stamp = new Stamp(hostAsset.Name, dependencyAssetName); + if (m_AnalyzedStamps.Contains(stamp)) + { + continue; + } + + m_AnalyzedStamps.Add(stamp); + + string guid = AssetDatabase.AssetPathToGUID(dependencyAssetName); + if (string.IsNullOrEmpty(guid)) + { + Debug.LogWarning(Utility.Text.Format("Can not find guid by asset '{0}'.", dependencyAssetName)); + continue; + } + + Asset asset = m_ResourceCollection.GetAsset(guid); + if (asset != null) + { + dependencyData.AddDependencyAsset(asset); + } + else + { + dependencyData.AddScatteredDependencyAsset(dependencyAssetName); + + List scatteredAssets = null; + if (!m_ScatteredAssets.TryGetValue(dependencyAssetName, out scatteredAssets)) + { + scatteredAssets = new List(); + m_ScatteredAssets.Add(dependencyAssetName, scatteredAssets); + } + + scatteredAssets.Add(hostAsset); + + AnalyzeAsset(dependencyAssetName, hostAsset, dependencyData, scriptAssetNames); + } + } + } + + public Asset GetAsset(string assetName) + { + return m_ResourceCollection.GetAsset(AssetDatabase.AssetPathToGUID(assetName)); + } + + public string[] GetAssetNames() + { + return GetAssetNames(AssetsOrder.AssetNameAsc, null); + } + + public string[] GetAssetNames(AssetsOrder order, string filter) + { + HashSet filteredAssetNames = GetFilteredAssetNames(filter); + IEnumerable> filteredResult = m_DependencyDatas.Where(pair => filteredAssetNames.Contains(pair.Key)); + IEnumerable> orderedResult = null; + switch (order) + { + case AssetsOrder.AssetNameAsc: + orderedResult = filteredResult.OrderBy(pair => pair.Key); + break; + + case AssetsOrder.AssetNameDesc: + orderedResult = filteredResult.OrderByDescending(pair => pair.Key); + break; + + case AssetsOrder.DependencyResourceCountAsc: + orderedResult = filteredResult.OrderBy(pair => pair.Value.DependencyResourceCount); + break; + + case AssetsOrder.DependencyResourceCountDesc: + orderedResult = filteredResult.OrderByDescending(pair => pair.Value.DependencyResourceCount); + break; + + case AssetsOrder.DependencyAssetCountAsc: + orderedResult = filteredResult.OrderBy(pair => pair.Value.DependencyAssetCount); + break; + + case AssetsOrder.DependencyAssetCountDesc: + orderedResult = filteredResult.OrderByDescending(pair => pair.Value.DependencyAssetCount); + break; + + case AssetsOrder.ScatteredDependencyAssetCountAsc: + orderedResult = filteredResult.OrderBy(pair => pair.Value.ScatteredDependencyAssetCount); + break; + + case AssetsOrder.ScatteredDependencyAssetCountDesc: + orderedResult = filteredResult.OrderByDescending(pair => pair.Value.ScatteredDependencyAssetCount); + break; + + default: + orderedResult = filteredResult; + break; + } + + return orderedResult.Select(pair => pair.Key).ToArray(); + } + + public DependencyData GetDependencyData(string assetName) + { + DependencyData dependencyData = null; + if (m_DependencyDatas.TryGetValue(assetName, out dependencyData)) + { + return dependencyData; + } + + return dependencyData; + } + + public string[] GetScatteredAssetNames() + { + return GetScatteredAssetNames(ScatteredAssetsOrder.HostAssetCountDesc, null); + } + + public string[] GetScatteredAssetNames(ScatteredAssetsOrder order, string filter) + { + HashSet filterAssetNames = GetFilteredAssetNames(filter); + IEnumerable>> filteredResult = m_ScatteredAssets.Where(pair => filterAssetNames.Contains(pair.Key) && pair.Value.Count > 1); + IEnumerable>> orderedResult = null; + switch (order) + { + case ScatteredAssetsOrder.AssetNameAsc: + orderedResult = filteredResult.OrderBy(pair => pair.Key); + break; + + case ScatteredAssetsOrder.AssetNameDesc: + orderedResult = filteredResult.OrderByDescending(pair => pair.Key); + break; + + case ScatteredAssetsOrder.HostAssetCountAsc: + orderedResult = filteredResult.OrderBy(pair => pair.Value.Count); + break; + + case ScatteredAssetsOrder.HostAssetCountDesc: + orderedResult = filteredResult.OrderByDescending(pair => pair.Value.Count); + break; + + default: + orderedResult = filteredResult; + break; + } + + return orderedResult.Select(pair => pair.Key).ToArray(); + } + + public Asset[] GetHostAssets(string scatteredAssetName) + { + List assets = null; + if (m_ScatteredAssets.TryGetValue(scatteredAssetName, out assets)) + { + return assets.ToArray(); + } + + return null; + } + + public string[][] GetCircularDependencyDatas() + { + return m_CircularDependencyDatas.ToArray(); + } + + private HashSet GetFilteredAssetNames(string filter) + { + string[] filterAssetGuids = AssetDatabase.FindAssets(filter); + HashSet filterAssetNames = new HashSet(); + foreach (string filterAssetGuid in filterAssetGuids) + { + filterAssetNames.Add(AssetDatabase.GUIDToAssetPath(filterAssetGuid)); + } + + return filterAssetNames; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.cs.meta new file mode 100644 index 0000000..e3411d0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ResourceAnalyzerController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f05a10a252bec6c44b19b0cf7c105ff3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ScatteredAssetsOrder.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ScatteredAssetsOrder.cs new file mode 100644 index 0000000..7e89eac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ScatteredAssetsOrder.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + public enum ScatteredAssetsOrder : byte + { + AssetNameAsc, + AssetNameDesc, + HostAssetCountAsc, + HostAssetCountDesc, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ScatteredAssetsOrder.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ScatteredAssetsOrder.cs.meta new file mode 100644 index 0000000..e5c159a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceAnalyzer/ScatteredAssetsOrder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d9068195c1bd334d8dfb4211ad27f7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder.meta new file mode 100644 index 0000000..cab48f7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2dd745915ad459e4c9d5aef04e1dfeea +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/AssetBundleCompressionType.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/AssetBundleCompressionType.cs new file mode 100644 index 0000000..90acffb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/AssetBundleCompressionType.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 对 AssetBundle 应用的压缩算法类型。 + /// + public enum AssetBundleCompressionType : byte + { + /// + /// 不使用压缩算法。 + /// + Uncompressed = 0, + + /// + /// 使用 LZ4 压缩算法。 + /// + LZ4, + + /// + /// 使用 LZMA 压缩算法。 + /// + LZMA + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/AssetBundleCompressionType.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/AssetBundleCompressionType.cs.meta new file mode 100644 index 0000000..0baf1ad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/AssetBundleCompressionType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 690743de30449bf46aa333e5117930d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/IBuildEventHandler.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/IBuildEventHandler.cs new file mode 100644 index 0000000..4a37246 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/IBuildEventHandler.cs @@ -0,0 +1,138 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 生成资源事件处理函数。 + /// + public interface IBuildEventHandler + { + /// + /// 获取当某个平台生成失败时,是否继续生成下一个平台。 + /// + bool ContinueOnFailure + { + get; + } + + /// + /// 所有平台生成开始前的预处理事件。 + /// + /// 产品名称。 + /// 公司名称。 + /// 游戏识别号。 + /// 游戏框架版本。 + /// Unity 版本。 + /// 适用游戏版本。 + /// 内部资源版本。 + /// 生成的目标平台。 + /// AssetBundle 压缩类型。 + /// 压缩解压缩辅助器类型名称。 + /// 是否进行再压缩以降低传输开销。 + /// 是否强制重新构建 AssetBundle。 + /// 生成资源事件处理函数名称。 + /// 生成目录。 + /// AssetBundle 生成选项。 + /// 生成时的工作路径。 + /// 是否生成单机模式所需的文件。 + /// 为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// 是否生成可更新模式所需的远程文件。 + /// 为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。 + /// 是否生成可更新模式所需的本地文件。 + /// 为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// 生成报告路径。 + void OnPreprocessAllPlatforms(string productName, string companyName, string gameIdentifier, string gameFrameworkVersion, string unityVersion, string applicableGameVersion, int internalResourceVersion, + Platform platforms, AssetBundleCompressionType assetBundleCompression, string compressionHelperTypeName, bool additionalCompressionSelected, bool forceRebuildAssetBundleSelected, string buildEventHandlerTypeName, string outputDirectory, BuildAssetBundleOptions buildAssetBundleOptions, + string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, string buildReportPath); + + /// + /// 某个平台生成开始前的预处理事件。 + /// + /// 生成平台。 + /// 生成时的工作路径。 + /// 是否生成单机模式所需的文件。 + /// 为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// 是否生成可更新模式所需的远程文件。 + /// 为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。 + /// 是否生成可更新模式所需的本地文件。 + /// 为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + void OnPreprocessPlatform(Platform platform, string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath); + + /// + /// 某个平台生成 AssetBundle 完成事件。 + /// + /// 生成平台。 + /// 生成时的工作路径。 + /// 是否生成单机模式所需的文件。 + /// 为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// 是否生成可更新模式所需的远程文件。 + /// 为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。 + /// 是否生成可更新模式所需的本地文件。 + /// 为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// AssetBundle 的描述文件。 + void OnBuildAssetBundlesComplete(Platform platform, string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, AssetBundleManifest assetBundleManifest); + + /// + /// 某个平台可更新模式版本列表文件的输出事件。 + /// + /// 生成平台。 + /// 可更新模式版本列表文件的路径。 + /// 可更新模式版本列表文件的长度。 + /// 可更新模式版本列表文件的校验值。 + /// 可更新模式版本列表文件压缩后的长度。 + /// 可更新模式版本列表文件压缩后的校验值。 + void OnOutputUpdatableVersionListData(Platform platform, string versionListPath, int versionListLength, int versionListHashCode, int versionListCompressedLength, int versionListCompressedHashCode); + + /// + /// 某个平台生成结束后的后处理事件。 + /// + /// 生成平台。 + /// 生成时的工作路径。 + /// 是否生成单机模式所需的文件。 + /// 为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// 是否生成可更新模式所需的远程文件。 + /// 为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。 + /// 是否生成可更新模式所需的本地文件。 + /// 为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// 是否生成成功。 + void OnPostprocessPlatform(Platform platform, string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, bool isSuccess); + + /// + /// 所有平台生成结束后的后处理事件。 + /// + /// 产品名称。 + /// 公司名称。 + /// 游戏识别号。 + /// 游戏框架版本。 + /// Unity 版本。 + /// 适用游戏版本。 + /// 内部资源版本。 + /// 生成的目标平台。 + /// AssetBundle 压缩类型。 + /// 压缩解压缩辅助器类型名称。 + /// 是否进行再压缩以降低传输开销。 + /// 是否强制重新构建 AssetBundle。 + /// 生成资源事件处理函数名称。 + /// 生成目录。 + /// AssetBundle 生成选项。 + /// 生成时的工作路径。 + /// 是否生成单机模式所需的文件。 + /// 为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// 是否生成可更新模式所需的远程文件。 + /// 为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。 + /// 是否生成可更新模式所需的本地文件。 + /// 为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。 + /// 生成报告路径。 + void OnPostprocessAllPlatforms(string productName, string companyName, string gameIdentifier, string gameFrameworkVersion, string unityVersion, string applicableGameVersion, int internalResourceVersion, + Platform platforms, AssetBundleCompressionType assetBundleCompression, string compressionHelperTypeName, bool additionalCompressionSelected, bool forceRebuildAssetBundleSelected, string buildEventHandlerTypeName, string outputDirectory, BuildAssetBundleOptions buildAssetBundleOptions, + string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, string buildReportPath); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/IBuildEventHandler.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/IBuildEventHandler.cs.meta new file mode 100644 index 0000000..80d99e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/IBuildEventHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a24c2d69ef707e94c8ec819667089bce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/Platform.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/Platform.cs new file mode 100644 index 0000000..35e7355 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/Platform.cs @@ -0,0 +1,57 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace UnityGameFramework.Editor.ResourceTools +{ + [Flags] + public enum Platform : int + { + Undefined = 0, + + /// + /// Windows 32 位。 + /// + Windows = 1 << 0, + + /// + /// Windows 64 位。 + /// + Windows64 = 1 << 1, + + /// + /// macOS。 + /// + MacOS = 1 << 2, + + /// + /// Linux。 + /// + Linux = 1 << 3, + + /// + /// iOS。 + /// + IOS = 1 << 4, + + /// + /// Android。 + /// + Android = 1 << 5, + + /// + /// Windows Store。 + /// + WindowsStore = 1 << 6, + + /// + /// WebGL。 + /// + WebGL = 1 << 7, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/Platform.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/Platform.cs.meta new file mode 100644 index 0000000..fb32acc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/Platform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 443d82794c390e043b1565cea8da60cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilder.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilder.cs new file mode 100644 index 0000000..a0c3cd6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilder.cs @@ -0,0 +1,513 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源生成器。 + /// + internal sealed class ResourceBuilder : EditorWindow + { + private ResourceBuilderController m_Controller = null; + private bool m_OrderBuildResources = false; + private int m_CompressionHelperTypeNameIndex = 0; + private int m_BuildEventHandlerTypeNameIndex = 0; + + [MenuItem("Game Framework/Resource Tools/Resource Builder", false, 40)] + private static void Open() + { + ResourceBuilder window = GetWindow("Resource Builder", true); +#if UNITY_2019_3_OR_NEWER + window.minSize = new Vector2(800f, 640f); +#else + window.minSize = new Vector2(800f, 600f); +#endif + } + + private void OnEnable() + { + m_Controller = new ResourceBuilderController(); + m_Controller.OnLoadingResource += OnLoadingResource; + m_Controller.OnLoadingAsset += OnLoadingAsset; + m_Controller.OnLoadCompleted += OnLoadCompleted; + m_Controller.OnAnalyzingAsset += OnAnalyzingAsset; + m_Controller.OnAnalyzeCompleted += OnAnalyzeCompleted; + m_Controller.ProcessingAssetBundle += OnProcessingAssetBundle; + m_Controller.ProcessingBinary += OnProcessingBinary; + m_Controller.ProcessResourceComplete += OnProcessResourceComplete; + m_Controller.BuildResourceError += OnBuildResourceError; + + m_OrderBuildResources = false; + + if (m_Controller.Load()) + { + Debug.Log("Load configuration success."); + + m_CompressionHelperTypeNameIndex = 0; + string[] compressionHelperTypeNames = m_Controller.GetCompressionHelperTypeNames(); + for (int i = 0; i < compressionHelperTypeNames.Length; i++) + { + if (m_Controller.CompressionHelperTypeName == compressionHelperTypeNames[i]) + { + m_CompressionHelperTypeNameIndex = i; + break; + } + } + + m_Controller.RefreshCompressionHelper(); + + m_BuildEventHandlerTypeNameIndex = 0; + string[] buildEventHandlerTypeNames = m_Controller.GetBuildEventHandlerTypeNames(); + for (int i = 0; i < buildEventHandlerTypeNames.Length; i++) + { + if (m_Controller.BuildEventHandlerTypeName == buildEventHandlerTypeNames[i]) + { + m_BuildEventHandlerTypeNameIndex = i; + break; + } + } + + m_Controller.RefreshBuildEventHandler(); + } + else + { + Debug.LogWarning("Load configuration failure."); + } + } + + private void Update() + { + if (m_OrderBuildResources) + { + m_OrderBuildResources = false; + BuildResources(); + } + } + + private void OnGUI() + { + EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height)); + { + GUILayout.Space(5f); + EditorGUILayout.LabelField("Environment Information", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Product Name", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.ProductName); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Company Name", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.CompanyName); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Game Identifier", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.GameIdentifier); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Game Framework Version", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.GameFrameworkVersion); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Unity Version", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.UnityVersion); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Applicable Game Version", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.ApplicableGameVersion); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + GUILayout.Space(5f); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.BeginVertical(); + { + EditorGUILayout.LabelField("Platforms", EditorStyles.boldLabel); + EditorGUILayout.BeginHorizontal("box"); + { + EditorGUILayout.BeginVertical(); + { + DrawPlatform(Platform.Windows, "Windows"); + DrawPlatform(Platform.Windows64, "Windows x64"); + DrawPlatform(Platform.MacOS, "macOS"); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.BeginVertical(); + { + DrawPlatform(Platform.Linux, "Linux"); + DrawPlatform(Platform.IOS, "iOS"); + DrawPlatform(Platform.Android, "Android"); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.BeginVertical(); + { + DrawPlatform(Platform.WindowsStore, "Windows Store"); + DrawPlatform(Platform.WebGL, "WebGL"); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndHorizontal(); + GUILayout.Space(5f); + EditorGUILayout.LabelField("Compression", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("AssetBundle Compression", GUILayout.Width(160f)); + m_Controller.AssetBundleCompression = (AssetBundleCompressionType)EditorGUILayout.EnumPopup(m_Controller.AssetBundleCompression); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Compression Helper", GUILayout.Width(160f)); + string[] names = m_Controller.GetCompressionHelperTypeNames(); + int selectedIndex = EditorGUILayout.Popup(m_CompressionHelperTypeNameIndex, names); + if (selectedIndex != m_CompressionHelperTypeNameIndex) + { + m_CompressionHelperTypeNameIndex = selectedIndex; + m_Controller.CompressionHelperTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex]; + if (m_Controller.RefreshCompressionHelper()) + { + Debug.Log("Set compression helper success."); + } + else + { + Debug.LogWarning("Set compression helper failure."); + } + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Additional Compression", GUILayout.Width(160f)); + m_Controller.AdditionalCompressionSelected = EditorGUILayout.ToggleLeft("Additional Compression for Output Full Resources with Compression Helper", m_Controller.AdditionalCompressionSelected); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + GUILayout.Space(5f); + EditorGUILayout.LabelField("Build", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Force Rebuild AssetBundle", GUILayout.Width(160f)); + m_Controller.ForceRebuildAssetBundleSelected = EditorGUILayout.Toggle(m_Controller.ForceRebuildAssetBundleSelected); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Build Event Handler", GUILayout.Width(160f)); + string[] names = m_Controller.GetBuildEventHandlerTypeNames(); + int selectedIndex = EditorGUILayout.Popup(m_BuildEventHandlerTypeNameIndex, names); + if (selectedIndex != m_BuildEventHandlerTypeNameIndex) + { + m_BuildEventHandlerTypeNameIndex = selectedIndex; + m_Controller.BuildEventHandlerTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex]; + if (m_Controller.RefreshBuildEventHandler()) + { + Debug.Log("Set build event handler success."); + } + else + { + Debug.LogWarning("Set build event handler failure."); + } + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Internal Resource Version", GUILayout.Width(160f)); + m_Controller.InternalResourceVersion = EditorGUILayout.IntField(m_Controller.InternalResourceVersion); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Resource Version", GUILayout.Width(160f)); + GUILayout.Label(Utility.Text.Format("{0} ({1})", m_Controller.ApplicableGameVersion, m_Controller.InternalResourceVersion)); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Output Directory", GUILayout.Width(160f)); + m_Controller.OutputDirectory = EditorGUILayout.TextField(m_Controller.OutputDirectory); + if (GUILayout.Button("Browse...", GUILayout.Width(80f))) + { + BrowseOutputDirectory(); + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Working Path", GUILayout.Width(160f)); + GUILayout.Label(m_Controller.WorkingPath); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUI.BeginDisabledGroup(!m_Controller.OutputPackageSelected); + EditorGUILayout.LabelField("Output Package Path", GUILayout.Width(160f)); + GUILayout.Label(m_Controller.OutputPackagePath); + EditorGUI.EndDisabledGroup(); + m_Controller.OutputPackageSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPackageSelected, GUILayout.Width(70f)); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUI.BeginDisabledGroup(!m_Controller.OutputFullSelected); + EditorGUILayout.LabelField("Output Full Path", GUILayout.Width(160f)); + GUILayout.Label(m_Controller.OutputFullPath); + EditorGUI.EndDisabledGroup(); + m_Controller.OutputFullSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputFullSelected, GUILayout.Width(70f)); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUI.BeginDisabledGroup(!m_Controller.OutputPackedSelected); + EditorGUILayout.LabelField("Output Packed Path", GUILayout.Width(160f)); + GUILayout.Label(m_Controller.OutputPackedPath); + EditorGUI.EndDisabledGroup(); + m_Controller.OutputPackedSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPackedSelected, GUILayout.Width(70f)); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Build Report Path", GUILayout.Width(160f)); + GUILayout.Label(m_Controller.BuildReportPath); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + string buildMessage = string.Empty; + MessageType buildMessageType = MessageType.None; + GetBuildMessage(out buildMessage, out buildMessageType); + EditorGUILayout.HelpBox(buildMessage, buildMessageType); + GUILayout.Space(2f); + EditorGUILayout.BeginHorizontal(); + { + EditorGUI.BeginDisabledGroup(m_Controller.Platforms == Platform.Undefined || string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName) || !m_Controller.IsValidOutputDirectory); + { + if (GUILayout.Button("Start Build Resources")) + { + m_OrderBuildResources = true; + } + } + EditorGUI.EndDisabledGroup(); + if (GUILayout.Button("Save", GUILayout.Width(80f))) + { + SaveConfiguration(); + } + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + } + + private void BrowseOutputDirectory() + { + string directory = EditorUtility.OpenFolderPanel("Select Output Directory", m_Controller.OutputDirectory, string.Empty); + if (!string.IsNullOrEmpty(directory)) + { + m_Controller.OutputDirectory = directory; + } + } + + private void GetBuildMessage(out string message, out MessageType messageType) + { + message = string.Empty; + messageType = MessageType.Error; + if (m_Controller.Platforms == Platform.Undefined) + { + if (!string.IsNullOrEmpty(message)) + { + message += Environment.NewLine; + } + + message += "Platform is invalid."; + } + + if (string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName)) + { + if (!string.IsNullOrEmpty(message)) + { + message += Environment.NewLine; + } + + message += "Compression helper is invalid."; + } + + if (!m_Controller.IsValidOutputDirectory) + { + if (!string.IsNullOrEmpty(message)) + { + message += Environment.NewLine; + } + + message += "Output directory is invalid."; + } + + if (!string.IsNullOrEmpty(message)) + { + return; + } + + messageType = MessageType.Info; + if (Directory.Exists(m_Controller.OutputPackagePath)) + { + message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputPackagePath); + messageType = MessageType.Warning; + } + + if (Directory.Exists(m_Controller.OutputFullPath)) + { + if (message.Length > 0) + { + message += " "; + } + + message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputFullPath); + messageType = MessageType.Warning; + } + + if (Directory.Exists(m_Controller.OutputPackedPath)) + { + if (message.Length > 0) + { + message += " "; + } + + message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputPackedPath); + messageType = MessageType.Warning; + } + + if (messageType == MessageType.Warning) + { + return; + } + + message = "Ready to build."; + } + + private void BuildResources() + { + if (m_Controller.BuildResources()) + { + Debug.Log("Build resources success."); + SaveConfiguration(); + } + else + { + Debug.LogWarning("Build resources failure."); + } + } + + private void SaveConfiguration() + { + if (m_Controller.Save()) + { + Debug.Log("Save configuration success."); + } + else + { + Debug.LogWarning("Save configuration failure."); + } + } + + private void DrawPlatform(Platform platform, string platformName) + { + m_Controller.SelectPlatform(platform, EditorGUILayout.ToggleLeft(platformName, m_Controller.IsPlatformSelected(platform))); + } + + private void OnLoadingResource(int index, int count) + { + EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index, count), (float)index / count); + } + + private void OnLoadingAsset(int index, int count) + { + EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index, count), (float)index / count); + } + + private void OnLoadCompleted() + { + EditorUtility.ClearProgressBar(); + } + + private void OnAnalyzingAsset(int index, int count) + { + EditorUtility.DisplayProgressBar("Analyzing Assets", Utility.Text.Format("Analyzing assets, {0}/{1} analyzed.", index, count), (float)index / count); + } + + private void OnAnalyzeCompleted() + { + EditorUtility.ClearProgressBar(); + } + + private bool OnProcessingAssetBundle(string assetBundleName, float progress) + { + if (EditorUtility.DisplayCancelableProgressBar("Processing AssetBundle", Utility.Text.Format("Processing '{0}'...", assetBundleName), progress)) + { + EditorUtility.ClearProgressBar(); + return true; + } + else + { + Repaint(); + return false; + } + } + + private bool OnProcessingBinary(string binaryName, float progress) + { + if (EditorUtility.DisplayCancelableProgressBar("Processing Binary", Utility.Text.Format("Processing '{0}'...", binaryName), progress)) + { + EditorUtility.ClearProgressBar(); + return true; + } + else + { + Repaint(); + return false; + } + } + + private void OnProcessResourceComplete(Platform platform) + { + EditorUtility.ClearProgressBar(); + Debug.Log(Utility.Text.Format("Build resources for '{0}' complete.", platform)); + } + + private void OnBuildResourceError(string errorMessage) + { + EditorUtility.ClearProgressBar(); + Debug.LogWarning(Utility.Text.Format("Build resources error with error message '{0}'.", errorMessage)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilder.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilder.cs.meta new file mode 100644 index 0000000..afd9986 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e863c5f9e4c0a9d47a926fbb0416a149 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderConfigPathAttribute.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderConfigPathAttribute.cs new file mode 100644 index 0000000..0632b22 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderConfigPathAttribute.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// ResourceBuilder 配置路径属性。 + /// + public sealed class ResourceBuilderConfigPathAttribute : ConfigPathAttribute + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderConfigPathAttribute.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderConfigPathAttribute.cs.meta new file mode 100644 index 0000000..a5d18b4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderConfigPathAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 099a19e921c6da944ba2cdf51139d818 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.AssetData.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.AssetData.cs new file mode 100644 index 0000000..1431d4b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.AssetData.cs @@ -0,0 +1,67 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceBuilderController + { + private sealed class AssetData + { + private readonly string m_Guid; + private readonly string m_Name; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly string[] m_DependencyAssetNames; + + public AssetData(string guid, string name, int length, int hashCode, string[] dependencyAssetNames) + { + m_Guid = guid; + m_Name = name; + m_Length = length; + m_HashCode = hashCode; + m_DependencyAssetNames = dependencyAssetNames; + } + + public string Guid + { + get + { + return m_Guid; + } + } + + public string Name + { + get + { + return m_Name; + } + } + + public int Length + { + get + { + return m_Length; + } + } + + public int HashCode + { + get + { + return m_HashCode; + } + } + + public string[] GetDependencyAssetNames() + { + return m_DependencyAssetNames; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.AssetData.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.AssetData.cs.meta new file mode 100644 index 0000000..472e462 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.AssetData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b52ab112713ba504a84693edd59a6b03 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.BuildReport.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.BuildReport.cs new file mode 100644 index 0000000..332a9f6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.BuildReport.cs @@ -0,0 +1,276 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Xml; +using UnityEditor; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceBuilderController + { + private sealed class BuildReport + { + private const string BuildReportName = "BuildReport.xml"; + private const string BuildLogName = "BuildLog.txt"; + + private string m_BuildReportName = null; + private string m_BuildLogName = null; + private string m_ProductName = null; + private string m_CompanyName = null; + private string m_GameIdentifier = null; + private string m_GameFrameworkVersion = null; + private string m_UnityVersion = null; + private string m_ApplicableGameVersion = null; + private int m_InternalResourceVersion = 0; + private Platform m_Platforms = Platform.Undefined; + private AssetBundleCompressionType m_AssetBundleCompression; + private string m_CompressionHelperTypeName; + private bool m_AdditionalCompressionSelected = false; + private bool m_ForceRebuildAssetBundleSelected = false; + private string m_BuildEventHandlerTypeName; + private string m_OutputDirectory; + private BuildAssetBundleOptions m_BuildAssetBundleOptions = BuildAssetBundleOptions.None; + private StringBuilder m_LogBuilder = null; + private SortedDictionary m_ResourceDatas = null; + + public void Initialize(string buildReportPath, string productName, string companyName, string gameIdentifier, string gameFrameworkVersion, string unityVersion, string applicableGameVersion, int internalResourceVersion, + Platform platforms, AssetBundleCompressionType assetBundleCompression, string compressionHelperTypeName, bool additionalCompressionSelected, bool forceRebuildAssetBundleSelected, string buildEventHandlerTypeName, string outputDirectory, BuildAssetBundleOptions buildAssetBundleOptions, SortedDictionary resourceDatas) + { + if (string.IsNullOrEmpty(buildReportPath)) + { + throw new GameFrameworkException("Build report path is invalid."); + } + + m_BuildReportName = Utility.Path.GetRegularPath(Path.Combine(buildReportPath, BuildReportName)); + m_BuildLogName = Utility.Path.GetRegularPath(Path.Combine(buildReportPath, BuildLogName)); + m_ProductName = productName; + m_CompanyName = companyName; + m_GameIdentifier = gameIdentifier; + m_GameFrameworkVersion = gameFrameworkVersion; + m_UnityVersion = unityVersion; + m_ApplicableGameVersion = applicableGameVersion; + m_InternalResourceVersion = internalResourceVersion; + m_Platforms = platforms; + m_AssetBundleCompression = assetBundleCompression; + m_CompressionHelperTypeName = compressionHelperTypeName; + m_AdditionalCompressionSelected = additionalCompressionSelected; + m_ForceRebuildAssetBundleSelected = forceRebuildAssetBundleSelected; + m_BuildEventHandlerTypeName = buildEventHandlerTypeName; + m_OutputDirectory = outputDirectory; + m_BuildAssetBundleOptions = buildAssetBundleOptions; + m_LogBuilder = new StringBuilder(); + m_ResourceDatas = resourceDatas; + } + + public void LogInfo(string format, params object[] args) + { + LogInternal("INFO", format, args); + } + + public void LogWarning(string format, params object[] args) + { + LogInternal("WARNING", format, args); + } + + public void LogError(string format, params object[] args) + { + LogInternal("ERROR", format, args); + } + + public void LogFatal(string format, params object[] args) + { + LogInternal("FATAL", format, args); + } + + public void SaveReport() + { + XmlElement xmlElement = null; + XmlAttribute xmlAttribute = null; + + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.AppendChild(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null)); + + XmlElement xmlRoot = xmlDocument.CreateElement("UnityGameFramework"); + xmlDocument.AppendChild(xmlRoot); + + XmlElement xmlBuildReport = xmlDocument.CreateElement("BuildReport"); + xmlRoot.AppendChild(xmlBuildReport); + + XmlElement xmlSummary = xmlDocument.CreateElement("Summary"); + xmlBuildReport.AppendChild(xmlSummary); + + xmlElement = xmlDocument.CreateElement("ProductName"); + xmlElement.InnerText = m_ProductName; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("CompanyName"); + xmlElement.InnerText = m_CompanyName; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("GameIdentifier"); + xmlElement.InnerText = m_GameIdentifier; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("GameFrameworkVersion"); + xmlElement.InnerText = m_GameFrameworkVersion; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("UnityVersion"); + xmlElement.InnerText = m_UnityVersion; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("ApplicableGameVersion"); + xmlElement.InnerText = m_ApplicableGameVersion; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("InternalResourceVersion"); + xmlElement.InnerText = m_InternalResourceVersion.ToString(); + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("Platforms"); + xmlElement.InnerText = m_Platforms.ToString(); + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("AssetBundleCompression"); + xmlElement.InnerText = m_AssetBundleCompression.ToString(); + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("CompressionHelperTypeName"); + xmlElement.InnerText = m_CompressionHelperTypeName; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("AdditionalCompressionSelected"); + xmlElement.InnerText = m_AdditionalCompressionSelected.ToString(); + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("ForceRebuildAssetBundleSelected"); + xmlElement.InnerText = m_ForceRebuildAssetBundleSelected.ToString(); + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("BuildEventHandlerTypeName"); + xmlElement.InnerText = m_BuildEventHandlerTypeName; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("OutputDirectory"); + xmlElement.InnerText = m_OutputDirectory; + xmlSummary.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("BuildAssetBundleOptions"); + xmlElement.InnerText = m_BuildAssetBundleOptions.ToString(); + xmlSummary.AppendChild(xmlElement); + + XmlElement xmlResources = xmlDocument.CreateElement("Resources"); + xmlAttribute = xmlDocument.CreateAttribute("Count"); + xmlAttribute.Value = m_ResourceDatas.Count.ToString(); + xmlResources.Attributes.SetNamedItem(xmlAttribute); + xmlBuildReport.AppendChild(xmlResources); + foreach (ResourceData resourceData in m_ResourceDatas.Values) + { + XmlElement xmlResource = xmlDocument.CreateElement("Resource"); + xmlAttribute = xmlDocument.CreateAttribute("Name"); + xmlAttribute.Value = resourceData.Name; + xmlResource.Attributes.SetNamedItem(xmlAttribute); + if (resourceData.Variant != null) + { + xmlAttribute = xmlDocument.CreateAttribute("Variant"); + xmlAttribute.Value = resourceData.Variant; + xmlResource.Attributes.SetNamedItem(xmlAttribute); + } + + xmlAttribute = xmlDocument.CreateAttribute("Extension"); + xmlAttribute.Value = GetExtension(resourceData); + xmlResource.Attributes.SetNamedItem(xmlAttribute); + + if (resourceData.FileSystem != null) + { + xmlAttribute = xmlDocument.CreateAttribute("FileSystem"); + xmlAttribute.Value = resourceData.FileSystem; + xmlResource.Attributes.SetNamedItem(xmlAttribute); + } + + xmlAttribute = xmlDocument.CreateAttribute("LoadType"); + xmlAttribute.Value = ((byte)resourceData.LoadType).ToString(); + xmlResource.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("Packed"); + xmlAttribute.Value = resourceData.Packed.ToString(); + xmlResource.Attributes.SetNamedItem(xmlAttribute); + string[] resourceGroups = resourceData.GetResourceGroups(); + if (resourceGroups.Length > 0) + { + xmlAttribute = xmlDocument.CreateAttribute("ResourceGroups"); + xmlAttribute.Value = string.Join(",", resourceGroups); + xmlResource.Attributes.SetNamedItem(xmlAttribute); + } + + xmlResources.AppendChild(xmlResource); + + AssetData[] assetDatas = resourceData.GetAssetDatas(); + XmlElement xmlAssets = xmlDocument.CreateElement("Assets"); + xmlAttribute = xmlDocument.CreateAttribute("Count"); + xmlAttribute.Value = assetDatas.Length.ToString(); + xmlAssets.Attributes.SetNamedItem(xmlAttribute); + xmlResource.AppendChild(xmlAssets); + foreach (AssetData assetData in assetDatas) + { + XmlElement xmlAsset = xmlDocument.CreateElement("Asset"); + xmlAttribute = xmlDocument.CreateAttribute("Guid"); + xmlAttribute.Value = assetData.Guid; + xmlAsset.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("Name"); + xmlAttribute.Value = assetData.Name; + xmlAsset.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("Length"); + xmlAttribute.Value = assetData.Length.ToString(); + xmlAsset.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("HashCode"); + xmlAttribute.Value = assetData.HashCode.ToString(); + xmlAsset.Attributes.SetNamedItem(xmlAttribute); + xmlAssets.AppendChild(xmlAsset); + string[] dependencyAssetNames = assetData.GetDependencyAssetNames(); + if (dependencyAssetNames.Length > 0) + { + XmlElement xmlDependencyAssets = xmlDocument.CreateElement("DependencyAssets"); + xmlAttribute = xmlDocument.CreateAttribute("Count"); + xmlAttribute.Value = dependencyAssetNames.Length.ToString(); + xmlDependencyAssets.Attributes.SetNamedItem(xmlAttribute); + xmlAsset.AppendChild(xmlDependencyAssets); + foreach (string dependencyAssetName in dependencyAssetNames) + { + XmlElement xmlDependencyAsset = xmlDocument.CreateElement("DependencyAsset"); + xmlAttribute = xmlDocument.CreateAttribute("Name"); + xmlAttribute.Value = dependencyAssetName; + xmlDependencyAsset.Attributes.SetNamedItem(xmlAttribute); + xmlDependencyAssets.AppendChild(xmlDependencyAsset); + } + } + } + + XmlElement xmlCodes = xmlDocument.CreateElement("Codes"); + xmlResource.AppendChild(xmlCodes); + foreach (ResourceCode resourceCode in resourceData.GetCodes()) + { + XmlElement xmlCode = xmlDocument.CreateElement(resourceCode.Platform.ToString()); + xmlAttribute = xmlDocument.CreateAttribute("Length"); + xmlAttribute.Value = resourceCode.Length.ToString(); + xmlCode.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("HashCode"); + xmlAttribute.Value = resourceCode.HashCode.ToString(); + xmlCode.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("CompressedLength"); + xmlAttribute.Value = resourceCode.CompressedLength.ToString(); + xmlCode.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("CompressedHashCode"); + xmlAttribute.Value = resourceCode.CompressedHashCode.ToString(); + xmlCode.Attributes.SetNamedItem(xmlAttribute); + xmlCodes.AppendChild(xmlCode); + } + } + + xmlDocument.Save(m_BuildReportName); + File.WriteAllText(m_BuildLogName, m_LogBuilder.ToString()); + } + + private void LogInternal(string type, string format, object[] args) + { + m_LogBuilder.AppendFormat("[{0:HH:mm:ss.fff}][{1}] ", DateTime.UtcNow.ToLocalTime(), type); + m_LogBuilder.AppendFormat(format, args); + m_LogBuilder.AppendLine(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.BuildReport.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.BuildReport.cs.meta new file mode 100644 index 0000000..70bd108 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.BuildReport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae0020ba4726cbd46b34a2341c16cd6a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.FileSystemHelper.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.FileSystemHelper.cs new file mode 100644 index 0000000..a0bd80a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.FileSystemHelper.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceBuilderController + { + private sealed class FileSystemHelper : IFileSystemHelper + { + public FileSystemStream CreateFileSystemStream(string fullPath, FileSystemAccess access, bool createNew) + { + return new CommonFileSystemStream(fullPath, access, createNew); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.FileSystemHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.FileSystemHelper.cs.meta new file mode 100644 index 0000000..754d7b6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.FileSystemHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23c25a2b879a092409b04f2e7851ac6b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceCode.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceCode.cs new file mode 100644 index 0000000..2d0358f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceCode.cs @@ -0,0 +1,70 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceBuilderController + { + private sealed class ResourceCode + { + private readonly Platform m_Platform; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly int m_CompressedLength; + private readonly int m_CompressedHashCode; + + public ResourceCode(Platform platform, int length, int hashCode, int compressedLength, int compressedHashCode) + { + m_Platform = platform; + m_Length = length; + m_HashCode = hashCode; + m_CompressedLength = compressedLength; + m_CompressedHashCode = compressedHashCode; + } + + public Platform Platform + { + get + { + return m_Platform; + } + } + + public int Length + { + get + { + return m_Length; + } + } + + public int HashCode + { + get + { + return m_HashCode; + } + } + + public int CompressedLength + { + get + { + return m_CompressedLength; + } + } + + public int CompressedHashCode + { + get + { + return m_CompressedHashCode; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceCode.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceCode.cs.meta new file mode 100644 index 0000000..65a19fa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86943b1b61e58a340b707c7c11f47700 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceData.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceData.cs new file mode 100644 index 0000000..ad9afbd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceData.cs @@ -0,0 +1,167 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceBuilderController + { + private sealed class ResourceData + { + private readonly string m_Name; + private readonly string m_Variant; + private readonly string m_FileSystem; + private readonly LoadType m_LoadType; + private readonly bool m_Packed; + private readonly string[] m_ResourceGroups; + private readonly List m_AssetDatas; + private readonly List m_Codes; + + public ResourceData(string name, string variant, string fileSystem, LoadType loadType, bool packed, string[] resourceGroups) + { + m_Name = name; + m_Variant = variant; + m_FileSystem = fileSystem; + m_LoadType = loadType; + m_Packed = packed; + m_ResourceGroups = resourceGroups; + m_AssetDatas = new List(); + m_Codes = new List(); + } + + public string Name + { + get + { + return m_Name; + } + } + + public string Variant + { + get + { + return m_Variant; + } + } + + public string FileSystem + { + get + { + return m_FileSystem; + } + } + + public bool IsLoadFromBinary + { + get + { + return m_LoadType == LoadType.LoadFromBinary || m_LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || m_LoadType == LoadType.LoadFromBinaryAndDecrypt; + } + } + + public LoadType LoadType + { + get + { + return m_LoadType; + } + } + + public bool Packed + { + get + { + return m_Packed; + } + } + + public int AssetCount + { + get + { + return m_AssetDatas.Count; + } + } + + public string[] GetResourceGroups() + { + return m_ResourceGroups; + } + + public string[] GetAssetGuids() + { + string[] assetGuids = new string[m_AssetDatas.Count]; + for (int i = 0; i < m_AssetDatas.Count; i++) + { + assetGuids[i] = m_AssetDatas[i].Guid; + } + + return assetGuids; + } + + public string[] GetAssetNames() + { + string[] assetNames = new string[m_AssetDatas.Count]; + for (int i = 0; i < m_AssetDatas.Count; i++) + { + assetNames[i] = m_AssetDatas[i].Name; + } + + return assetNames; + } + + public AssetData[] GetAssetDatas() + { + return m_AssetDatas.ToArray(); + } + + public AssetData GetAssetData(string assetName) + { + foreach (AssetData assetData in m_AssetDatas) + { + if (assetData.Name == assetName) + { + return assetData; + } + } + + return null; + } + + public void AddAssetData(string guid, string name, int length, int hashCode, string[] dependencyAssetNames) + { + m_AssetDatas.Add(new AssetData(guid, name, length, hashCode, dependencyAssetNames)); + } + + public ResourceCode GetCode(Platform platform) + { + foreach (ResourceCode code in m_Codes) + { + if (code.Platform == platform) + { + return code; + } + } + + return null; + } + + public ResourceCode[] GetCodes() + { + return m_Codes.ToArray(); + } + + public void AddCode(Platform platform, int length, int hashCode, int compressedLength, int compressedHashCode) + { + m_Codes.Add(new ResourceCode(platform, length, hashCode, compressedLength, compressedHashCode)); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceData.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceData.cs.meta new file mode 100644 index 0000000..5a662b5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.ResourceData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61757cf57a877ce46a12429a7e8996dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.VersionListData.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.VersionListData.cs new file mode 100644 index 0000000..f45746d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.VersionListData.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceBuilderController + { + private sealed class VersionListData + { + public VersionListData(string path, int length, int hashCode, int compressedLength, int compressedHashCode) + { + Path = path; + Length = length; + HashCode = hashCode; + CompressedLength = compressedLength; + CompressedHashCode = compressedHashCode; + } + + public string Path + { + get; + private set; + } + + public int Length + { + get; + private set; + } + + public int HashCode + { + get; + private set; + } + + public int CompressedLength + { + get; + private set; + } + + public int CompressedHashCode + { + get; + private set; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.VersionListData.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.VersionListData.cs.meta new file mode 100644 index 0000000..77b014a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.VersionListData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c69cd2ac760709b4ab36ba15bc5d8759 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.cs new file mode 100644 index 0000000..1c039ac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.cs @@ -0,0 +1,1567 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.FileSystem; +using GameFramework.Resource; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed partial class ResourceBuilderController + { + private const string RemoteVersionListFileName = "GameFrameworkVersion.dat"; + private const string LocalVersionListFileName = "GameFrameworkList.dat"; + private const string DefaultExtension = "dat"; + private const string NoneOptionName = ""; + private static readonly int AssetsStringLength = "Assets".Length; + + private readonly string m_ConfigurationPath; + private readonly ResourceCollection m_ResourceCollection; + private readonly ResourceAnalyzerController m_ResourceAnalyzerController; + private readonly SortedDictionary m_ResourceDatas; + private readonly Dictionary m_OutputPackageFileSystems; + private readonly Dictionary m_OutputPackedFileSystems; + private readonly BuildReport m_BuildReport; + private readonly List m_CompressionHelperTypeNames; + private readonly List m_BuildEventHandlerTypeNames; + private IBuildEventHandler m_BuildEventHandler; + private IFileSystemManager m_FileSystemManager; + + public ResourceBuilderController() + { + m_ConfigurationPath = Type.GetConfigurationPath() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/ResourceBuilder.xml")); + + m_ResourceCollection = new ResourceCollection(); + m_ResourceCollection.OnLoadingResource += delegate (int index, int count) + { + if (OnLoadingResource != null) + { + OnLoadingResource(index, count); + } + }; + + m_ResourceCollection.OnLoadingAsset += delegate (int index, int count) + { + if (OnLoadingAsset != null) + { + OnLoadingAsset(index, count); + } + }; + + m_ResourceCollection.OnLoadCompleted += delegate () + { + if (OnLoadCompleted != null) + { + OnLoadCompleted(); + } + }; + + m_ResourceAnalyzerController = new ResourceAnalyzerController(m_ResourceCollection); + + m_ResourceAnalyzerController.OnAnalyzingAsset += delegate (int index, int count) + { + if (OnAnalyzingAsset != null) + { + OnAnalyzingAsset(index, count); + } + }; + + m_ResourceAnalyzerController.OnAnalyzeCompleted += delegate () + { + if (OnAnalyzeCompleted != null) + { + OnAnalyzeCompleted(); + } + }; + + m_ResourceDatas = new SortedDictionary(StringComparer.Ordinal); + m_OutputPackageFileSystems = new Dictionary(StringComparer.Ordinal); + m_OutputPackedFileSystems = new Dictionary(StringComparer.Ordinal); + m_BuildReport = new BuildReport(); + + m_CompressionHelperTypeNames = new List + { + NoneOptionName + }; + + m_BuildEventHandlerTypeNames = new List + { + NoneOptionName + }; + + m_CompressionHelperTypeNames.AddRange(Type.GetRuntimeOrEditorTypeNames(typeof(Utility.Compression.ICompressionHelper))); + m_BuildEventHandlerTypeNames.AddRange(Type.GetRuntimeOrEditorTypeNames(typeof(IBuildEventHandler))); + m_BuildEventHandler = null; + m_FileSystemManager = null; + + Platforms = Platform.Undefined; + AssetBundleCompression = AssetBundleCompressionType.LZ4; + CompressionHelperTypeName = string.Empty; + AdditionalCompressionSelected = false; + ForceRebuildAssetBundleSelected = false; + BuildEventHandlerTypeName = string.Empty; + OutputDirectory = string.Empty; + OutputPackageSelected = OutputFullSelected = OutputPackedSelected = true; + } + + public string ProductName + { + get + { + return PlayerSettings.productName; + } + } + + public string CompanyName + { + get + { + return PlayerSettings.companyName; + } + } + + public string GameIdentifier + { + get + { +#if UNITY_5_6_OR_NEWER + return PlayerSettings.applicationIdentifier; +#else + return PlayerSettings.bundleIdentifier; +#endif + } + } + + public string GameFrameworkVersion + { + get + { + return GameFramework.Version.GameFrameworkVersion; + } + } + + public string UnityVersion + { + get + { + return Application.unityVersion; + } + } + + public string ApplicableGameVersion + { + get + { + return Application.version; + } + } + + public int InternalResourceVersion + { + get; + set; + } + + public Platform Platforms + { + get; + set; + } + + public AssetBundleCompressionType AssetBundleCompression + { + get; + set; + } + + public string CompressionHelperTypeName + { + get; + set; + } + + public bool AdditionalCompressionSelected + { + get; + set; + } + + public bool ForceRebuildAssetBundleSelected + { + get; + set; + } + + public string BuildEventHandlerTypeName + { + get; + set; + } + + public string OutputDirectory + { + get; + set; + } + + public bool OutputPackageSelected + { + get; + set; + } + + public bool OutputFullSelected + { + get; + set; + } + + public bool OutputPackedSelected + { + get; + set; + } + + public bool IsValidOutputDirectory + { + get + { + if (string.IsNullOrEmpty(OutputDirectory)) + { + return false; + } + + if (!Directory.Exists(OutputDirectory)) + { + return false; + } + + return true; + } + } + + public string WorkingPath + { + get + { + if (!IsValidOutputDirectory) + { + return string.Empty; + } + + return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Working/", OutputDirectory)).FullName); + } + } + + public string OutputPackagePath + { + get + { + if (!IsValidOutputDirectory) + { + return string.Empty; + } + + return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Package/{1}_{2}/", OutputDirectory, ApplicableGameVersion.Replace('.', '_'), InternalResourceVersion)).FullName); + } + } + + public string OutputFullPath + { + get + { + if (!IsValidOutputDirectory) + { + return string.Empty; + } + + return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Full/{1}_{2}/", OutputDirectory, ApplicableGameVersion.Replace('.', '_'), InternalResourceVersion)).FullName); + } + } + + public string OutputPackedPath + { + get + { + if (!IsValidOutputDirectory) + { + return string.Empty; + } + + return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Packed/{1}_{2}/", OutputDirectory, ApplicableGameVersion.Replace('.', '_'), InternalResourceVersion)).FullName); + } + } + + public string BuildReportPath + { + get + { + if (!IsValidOutputDirectory) + { + return string.Empty; + } + + return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/BuildReport/{1}_{2}/", OutputDirectory, ApplicableGameVersion.Replace('.', '_'), InternalResourceVersion)).FullName); + } + } + + public event GameFrameworkAction OnLoadingResource = null; + + public event GameFrameworkAction OnLoadingAsset = null; + + public event GameFrameworkAction OnLoadCompleted = null; + + public event GameFrameworkAction OnAnalyzingAsset = null; + + public event GameFrameworkAction OnAnalyzeCompleted = null; + + public event GameFrameworkFunc ProcessingAssetBundle = null; + + public event GameFrameworkFunc ProcessingBinary = null; + + public event GameFrameworkAction ProcessResourceComplete = null; + + public event GameFrameworkAction BuildResourceError = null; + + public bool Load() + { + if (!File.Exists(m_ConfigurationPath)) + { + return false; + } + + try + { + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.Load(m_ConfigurationPath); + XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework"); + XmlNode xmlEditor = xmlRoot.SelectSingleNode("ResourceBuilder"); + XmlNode xmlSettings = xmlEditor.SelectSingleNode("Settings"); + + XmlNodeList xmlNodeList = null; + XmlNode xmlNode = null; + + xmlNodeList = xmlSettings.ChildNodes; + for (int i = 0; i < xmlNodeList.Count; i++) + { + xmlNode = xmlNodeList.Item(i); + switch (xmlNode.Name) + { + case "InternalResourceVersion": + InternalResourceVersion = int.Parse(xmlNode.InnerText) + 1; + break; + + case "Platforms": + Platforms = (Platform)int.Parse(xmlNode.InnerText); + break; + + case "AssetBundleCompression": + AssetBundleCompression = (AssetBundleCompressionType)byte.Parse(xmlNode.InnerText); + break; + + case "CompressionHelperTypeName": + CompressionHelperTypeName = xmlNode.InnerText; + break; + + case "AdditionalCompressionSelected": + AdditionalCompressionSelected = bool.Parse(xmlNode.InnerText); + break; + + case "ForceRebuildAssetBundleSelected": + ForceRebuildAssetBundleSelected = bool.Parse(xmlNode.InnerText); + break; + + case "BuildEventHandlerTypeName": + BuildEventHandlerTypeName = xmlNode.InnerText; + break; + + case "OutputDirectory": + OutputDirectory = xmlNode.InnerText; + break; + + case "OutputPackageSelected": + OutputPackageSelected = bool.Parse(xmlNode.InnerText); + break; + + case "OutputFullSelected": + OutputFullSelected = bool.Parse(xmlNode.InnerText); + break; + + case "OutputPackedSelected": + OutputPackedSelected = bool.Parse(xmlNode.InnerText); + break; + } + } + } + catch + { + File.Delete(m_ConfigurationPath); + return false; + } + + return true; + } + + public bool Save() + { + try + { + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.AppendChild(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null)); + + XmlElement xmlRoot = xmlDocument.CreateElement("UnityGameFramework"); + xmlDocument.AppendChild(xmlRoot); + + XmlElement xmlBuilder = xmlDocument.CreateElement("ResourceBuilder"); + xmlRoot.AppendChild(xmlBuilder); + + XmlElement xmlSettings = xmlDocument.CreateElement("Settings"); + xmlBuilder.AppendChild(xmlSettings); + + XmlElement xmlElement = null; + + xmlElement = xmlDocument.CreateElement("InternalResourceVersion"); + xmlElement.InnerText = InternalResourceVersion.ToString(); + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("Platforms"); + xmlElement.InnerText = ((int)Platforms).ToString(); + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("AssetBundleCompression"); + xmlElement.InnerText = ((byte)AssetBundleCompression).ToString(); + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("CompressionHelperTypeName"); + xmlElement.InnerText = CompressionHelperTypeName; + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("AdditionalCompressionSelected"); + xmlElement.InnerText = AdditionalCompressionSelected.ToString(); + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("ForceRebuildAssetBundleSelected"); + xmlElement.InnerText = ForceRebuildAssetBundleSelected.ToString(); + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("BuildEventHandlerTypeName"); + xmlElement.InnerText = BuildEventHandlerTypeName; + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("OutputDirectory"); + xmlElement.InnerText = OutputDirectory; + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("OutputPackageSelected"); + xmlElement.InnerText = OutputPackageSelected.ToString(); + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("OutputFullSelected"); + xmlElement.InnerText = OutputFullSelected.ToString(); + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("OutputPackedSelected"); + xmlElement.InnerText = OutputPackedSelected.ToString(); + xmlSettings.AppendChild(xmlElement); + + string configurationDirectoryName = Path.GetDirectoryName(m_ConfigurationPath); + if (!Directory.Exists(configurationDirectoryName)) + { + Directory.CreateDirectory(configurationDirectoryName); + } + + xmlDocument.Save(m_ConfigurationPath); + AssetDatabase.Refresh(); + return true; + } + catch + { + if (File.Exists(m_ConfigurationPath)) + { + File.Delete(m_ConfigurationPath); + } + + return false; + } + } + + public string[] GetCompressionHelperTypeNames() + { + return m_CompressionHelperTypeNames.ToArray(); + } + + public string[] GetBuildEventHandlerTypeNames() + { + return m_BuildEventHandlerTypeNames.ToArray(); + } + + public bool IsPlatformSelected(Platform platform) + { + return (Platforms & platform) != 0; + } + + public void SelectPlatform(Platform platform, bool selected) + { + if (selected) + { + Platforms |= platform; + } + else + { + Platforms &= ~platform; + } + } + + public bool RefreshCompressionHelper() + { + bool retVal = false; + if (!string.IsNullOrEmpty(CompressionHelperTypeName) && m_CompressionHelperTypeNames.Contains(CompressionHelperTypeName)) + { + System.Type compressionHelperType = Utility.Assembly.GetType(CompressionHelperTypeName); + if (compressionHelperType != null) + { + Utility.Compression.ICompressionHelper compressionHelper = (Utility.Compression.ICompressionHelper)Activator.CreateInstance(compressionHelperType); + if (compressionHelper != null) + { + Utility.Compression.SetCompressionHelper(compressionHelper); + return true; + } + } + } + else + { + retVal = true; + } + + CompressionHelperTypeName = string.Empty; + Utility.Compression.SetCompressionHelper(null); + return retVal; + } + + public bool RefreshBuildEventHandler() + { + bool retVal = false; + if (!string.IsNullOrEmpty(BuildEventHandlerTypeName) && m_BuildEventHandlerTypeNames.Contains(BuildEventHandlerTypeName)) + { + System.Type buildEventHandlerType = Utility.Assembly.GetType(BuildEventHandlerTypeName); + if (buildEventHandlerType != null) + { + IBuildEventHandler buildEventHandler = (IBuildEventHandler)Activator.CreateInstance(buildEventHandlerType); + if (buildEventHandler != null) + { + m_BuildEventHandler = buildEventHandler; + return true; + } + } + } + else + { + retVal = true; + } + + BuildEventHandlerTypeName = string.Empty; + m_BuildEventHandler = null; + return retVal; + } + + public bool BuildResources() + { + if (!IsValidOutputDirectory) + { + return false; + } + + if (Directory.Exists(OutputPackagePath)) + { + Directory.Delete(OutputPackagePath, true); + } + + Directory.CreateDirectory(OutputPackagePath); + + if (Directory.Exists(OutputFullPath)) + { + Directory.Delete(OutputFullPath, true); + } + + Directory.CreateDirectory(OutputFullPath); + + if (Directory.Exists(OutputPackedPath)) + { + Directory.Delete(OutputPackedPath, true); + } + + Directory.CreateDirectory(OutputPackedPath); + + if (Directory.Exists(BuildReportPath)) + { + Directory.Delete(BuildReportPath, true); + } + + Directory.CreateDirectory(BuildReportPath); + + BuildAssetBundleOptions buildAssetBundleOptions = GetBuildAssetBundleOptions(); + m_BuildReport.Initialize(BuildReportPath, ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion, + Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions, m_ResourceDatas); + + try + { + m_BuildReport.LogInfo("Build Start Time: {0:yyyy-MM-dd HH:mm:ss.fff}", DateTime.UtcNow.ToLocalTime()); + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPreprocessAllPlatforms'..."); + m_BuildEventHandler.OnPreprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion, + Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions, + WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath); + } + + m_BuildReport.LogInfo("Start prepare resource collection..."); + if (!m_ResourceCollection.Load()) + { + m_BuildReport.LogError("Can not parse 'ResourceCollection.xml', please use 'Resource Editor' tool first."); + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessAllPlatforms'..."); + m_BuildEventHandler.OnPostprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion, + Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions, + WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath); + } + + m_BuildReport.SaveReport(); + return false; + } + + if (Platforms == Platform.Undefined) + { + m_BuildReport.LogError("Platform undefined."); + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessAllPlatforms'..."); + m_BuildEventHandler.OnPostprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion, + Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions, + WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath); + } + + m_BuildReport.SaveReport(); + return false; + } + + m_BuildReport.LogInfo("Prepare resource collection complete."); + m_BuildReport.LogInfo("Start analyze assets dependency..."); + + m_ResourceAnalyzerController.Analyze(); + + m_BuildReport.LogInfo("Analyze assets dependency complete."); + m_BuildReport.LogInfo("Start prepare build data..."); + + AssetBundleBuild[] assetBundleBuildDatas = null; + ResourceData[] assetBundleResourceDatas = null; + ResourceData[] binaryResourceDatas = null; + if (!PrepareBuildData(out assetBundleBuildDatas, out assetBundleResourceDatas, out binaryResourceDatas)) + { + m_BuildReport.LogError("Prepare resource build data failure."); + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessAllPlatforms'..."); + m_BuildEventHandler.OnPostprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion, + Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions, + WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath); + } + + m_BuildReport.SaveReport(); + return false; + } + + m_BuildReport.LogInfo("Prepare resource build data complete."); + m_BuildReport.LogInfo("Start build resources for selected platforms..."); + + bool watchResult = m_BuildEventHandler == null || !m_BuildEventHandler.ContinueOnFailure; + bool isSuccess = false; + isSuccess = BuildResources(Platform.Windows, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas); + + if (!watchResult || isSuccess) + { + isSuccess = BuildResources(Platform.Windows64, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas); + } + + if (!watchResult || isSuccess) + { + isSuccess = BuildResources(Platform.MacOS, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas); + } + + if (!watchResult || isSuccess) + { + isSuccess = BuildResources(Platform.Linux, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas); + } + + if (!watchResult || isSuccess) + { + isSuccess = BuildResources(Platform.IOS, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas); + } + + if (!watchResult || isSuccess) + { + isSuccess = BuildResources(Platform.Android, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas); + } + + if (!watchResult || isSuccess) + { + isSuccess = BuildResources(Platform.WindowsStore, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas); + } + + if (!watchResult || isSuccess) + { + isSuccess = BuildResources(Platform.WebGL, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas); + } + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessAllPlatforms'..."); + m_BuildEventHandler.OnPostprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion, + Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions, + WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath); + } + + m_BuildReport.LogInfo("Build resources for selected platforms complete."); + m_BuildReport.SaveReport(); + + return true; + } + catch (Exception exception) + { + string errorMessage = exception.ToString(); + m_BuildReport.LogFatal(errorMessage); + m_BuildReport.SaveReport(); + if (BuildResourceError != null) + { + BuildResourceError(errorMessage); + } + + return false; + } + finally + { + m_OutputPackageFileSystems.Clear(); + m_OutputPackedFileSystems.Clear(); + if (m_FileSystemManager != null) + { + GameFrameworkEntry.Shutdown(); + m_FileSystemManager = null; + } + } + } + + private bool BuildResources(Platform platform, AssetBundleBuild[] assetBundleBuildDatas, BuildAssetBundleOptions buildAssetBundleOptions, ResourceData[] assetBundleResourceDatas, ResourceData[] binaryResourceDatas) + { + if (!IsPlatformSelected(platform)) + { + return true; + } + + string platformName = platform.ToString(); + m_BuildReport.LogInfo("Start build resources for '{0}'...", platformName); + + string workingPath = Utility.Text.Format("{0}{1}/", WorkingPath, platformName); + m_BuildReport.LogInfo("Working path is '{0}'.", workingPath); + + string outputPackagePath = Utility.Text.Format("{0}{1}/", OutputPackagePath, platformName); + if (OutputPackageSelected) + { + Directory.CreateDirectory(outputPackagePath); + m_BuildReport.LogInfo("Output package is selected, path is '{0}'.", outputPackagePath); + } + else + { + m_BuildReport.LogInfo("Output package is not selected."); + } + + string outputFullPath = Utility.Text.Format("{0}{1}/", OutputFullPath, platformName); + if (OutputFullSelected) + { + Directory.CreateDirectory(outputFullPath); + m_BuildReport.LogInfo("Output full is selected, path is '{0}'.", outputFullPath); + } + else + { + m_BuildReport.LogInfo("Output full is not selected."); + } + + string outputPackedPath = Utility.Text.Format("{0}{1}/", OutputPackedPath, platformName); + if (OutputPackedSelected) + { + Directory.CreateDirectory(outputPackedPath); + m_BuildReport.LogInfo("Output packed is selected, path is '{0}'.", outputPackedPath); + } + else + { + m_BuildReport.LogInfo("Output packed is not selected."); + } + + // Clean working path + List validNames = new List(); + foreach (ResourceData assetBundleResourceData in assetBundleResourceDatas) + { + validNames.Add(GetResourceFullName(assetBundleResourceData.Name, assetBundleResourceData.Variant).ToLowerInvariant()); + } + + if (Directory.Exists(workingPath)) + { + Uri workingUri = new Uri(workingPath, UriKind.Absolute); + string[] fileNames = Directory.GetFiles(workingPath, "*", SearchOption.AllDirectories); + foreach (string fileName in fileNames) + { + if (fileName.EndsWith(".manifest", StringComparison.Ordinal)) + { + continue; + } + + string relativeName = workingUri.MakeRelativeUri(new Uri(fileName, UriKind.Absolute)).ToString(); + if (!validNames.Contains(relativeName)) + { + File.Delete(fileName); + } + } + + string[] manifestNames = Directory.GetFiles(workingPath, "*.manifest", SearchOption.AllDirectories); + foreach (string manifestName in manifestNames) + { + if (!File.Exists(manifestName.Substring(0, manifestName.LastIndexOf('.')))) + { + File.Delete(manifestName); + } + } + + Utility.Path.RemoveEmptyDirectory(workingPath); + } + + if (!Directory.Exists(workingPath)) + { + Directory.CreateDirectory(workingPath); + } + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPreprocessPlatform' for '{0}'...", platformName); + m_BuildEventHandler.OnPreprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath); + } + + // Build AssetBundles + m_BuildReport.LogInfo("Unity start build asset bundles for '{0}'...", platformName); + AssetBundleManifest assetBundleManifest = BuildPipeline.BuildAssetBundles(workingPath, assetBundleBuildDatas, buildAssetBundleOptions, GetBuildTarget(platform)); + if (assetBundleManifest == null) + { + m_BuildReport.LogError("Build asset bundles for '{0}' failure.", platformName); + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessPlatform' for '{0}'...", platformName); + m_BuildEventHandler.OnPostprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, false); + } + + return false; + } + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnBuildAssetBundlesComplete' for '{0}'...", platformName); + m_BuildEventHandler.OnBuildAssetBundlesComplete(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, assetBundleManifest); + } + + m_BuildReport.LogInfo("Unity build asset bundles for '{0}' complete.", platformName); + + // Create FileSystems + m_BuildReport.LogInfo("Start create file system for '{0}'...", platformName); + + if (OutputPackageSelected) + { + CreateFileSystems(m_ResourceDatas.Values, outputPackagePath, m_OutputPackageFileSystems); + } + + if (OutputPackedSelected) + { + CreateFileSystems(GetPackedResourceDatas(), outputPackedPath, m_OutputPackedFileSystems); + } + + m_BuildReport.LogInfo("Create file system for '{0}' complete.", platformName); + + // Process AssetBundles + for (int i = 0; i < assetBundleResourceDatas.Length; i++) + { + string fullName = GetResourceFullName(assetBundleResourceDatas[i].Name, assetBundleResourceDatas[i].Variant); + if (ProcessingAssetBundle != null) + { + if (ProcessingAssetBundle(fullName, (float)(i + 1) / assetBundleResourceDatas.Length)) + { + m_BuildReport.LogWarning("The build has been canceled by user."); + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessPlatform' for '{0}'...", platformName); + m_BuildEventHandler.OnPostprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, false); + } + + return false; + } + } + + m_BuildReport.LogInfo("Start process asset bundle '{0}' for '{1}'...", fullName, platformName); + + if (!ProcessAssetBundle(platform, workingPath, outputPackagePath, outputFullPath, outputPackedPath, AdditionalCompressionSelected, assetBundleResourceDatas[i].Name, assetBundleResourceDatas[i].Variant, assetBundleResourceDatas[i].FileSystem)) + { + return false; + } + + m_BuildReport.LogInfo("Process asset bundle '{0}' for '{1}' complete.", fullName, platformName); + } + + // Process Binaries + for (int i = 0; i < binaryResourceDatas.Length; i++) + { + string fullName = GetResourceFullName(binaryResourceDatas[i].Name, binaryResourceDatas[i].Variant); + if (ProcessingBinary != null) + { + if (ProcessingBinary(fullName, (float)(i + 1) / binaryResourceDatas.Length)) + { + m_BuildReport.LogWarning("The build has been canceled by user."); + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessPlatform' for '{0}'...", platformName); + m_BuildEventHandler.OnPostprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, false); + } + + return false; + } + } + + m_BuildReport.LogInfo("Start process binary '{0}' for '{1}'...", fullName, platformName); + + if (!ProcessBinary(platform, workingPath, outputPackagePath, outputFullPath, outputPackedPath, AdditionalCompressionSelected, binaryResourceDatas[i].Name, binaryResourceDatas[i].Variant, binaryResourceDatas[i].FileSystem)) + { + return false; + } + + m_BuildReport.LogInfo("Process binary '{0}' for '{1}' complete.", fullName, platformName); + } + + if (OutputPackageSelected) + { + ProcessPackageVersionList(outputPackagePath, platform); + m_BuildReport.LogInfo("Process package version list for '{0}' complete.", platformName); + } + + if (OutputFullSelected) + { + VersionListData versionListData = ProcessUpdatableVersionList(outputFullPath, platform); + m_BuildReport.LogInfo("Process updatable version list for '{0}' complete, updatable version list path is '{1}', length is '{2}', hash code is '{3}[0x{3:X8}]', compressed length is '{4}', compressed hash code is '{5}[0x{5:X8}]'.", platformName, versionListData.Path, versionListData.Length, versionListData.HashCode, versionListData.CompressedLength, versionListData.CompressedHashCode); + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnOutputUpdatableVersionListData' for '{0}'...", platformName); + m_BuildEventHandler.OnOutputUpdatableVersionListData(platform, versionListData.Path, versionListData.Length, versionListData.HashCode, versionListData.CompressedLength, versionListData.CompressedHashCode); + } + } + + if (OutputPackedSelected) + { + ProcessReadOnlyVersionList(outputPackedPath, platform); + m_BuildReport.LogInfo("Process read-only version list for '{0}' complete.", platformName); + } + + if (m_BuildEventHandler != null) + { + m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessPlatform' for '{0}'...", platformName); + m_BuildEventHandler.OnPostprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, true); + } + + if (ProcessResourceComplete != null) + { + ProcessResourceComplete(platform); + } + + m_BuildReport.LogInfo("Build resources for '{0}' success.", platformName); + return true; + } + + private bool ProcessAssetBundle(Platform platform, string workingPath, string outputPackagePath, string outputFullPath, string outputPackedPath, bool additionalCompressionSelected, string name, string variant, string fileSystem) + { + string fullName = GetResourceFullName(name, variant); + ResourceData resourceData = m_ResourceDatas[fullName]; + string workingName = Utility.Path.GetRegularPath(Path.Combine(workingPath, fullName.ToLowerInvariant())); + + byte[] bytes = File.ReadAllBytes(workingName); + int length = bytes.Length; + int hashCode = Utility.Verifier.GetCrc32(bytes); + int compressedLength = length; + int compressedHashCode = hashCode; + + byte[] hashBytes = Utility.Converter.GetBytes(hashCode); + if (resourceData.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt) + { + bytes = Utility.Encryption.GetQuickXorBytes(bytes, hashBytes); + } + else if (resourceData.LoadType == LoadType.LoadFromMemoryAndDecrypt) + { + bytes = Utility.Encryption.GetXorBytes(bytes, hashBytes); + } + + return ProcessOutput(platform, outputPackagePath, outputFullPath, outputPackedPath, additionalCompressionSelected, name, variant, fileSystem, resourceData, bytes, length, hashCode, compressedLength, compressedHashCode); + } + + private bool ProcessBinary(Platform platform, string workingPath, string outputPackagePath, string outputFullPath, string outputPackedPath, bool additionalCompressionSelected, string name, string variant, string fileSystem) + { + string fullName = GetResourceFullName(name, variant); + ResourceData resourceData = m_ResourceDatas[fullName]; + string assetName = resourceData.GetAssetNames()[0]; + string assetPath = Utility.Path.GetRegularPath(Application.dataPath.Substring(0, Application.dataPath.Length - AssetsStringLength) + assetName); + + byte[] bytes = File.ReadAllBytes(assetPath); + int length = bytes.Length; + int hashCode = Utility.Verifier.GetCrc32(bytes); + int compressedLength = length; + int compressedHashCode = hashCode; + + byte[] hashBytes = Utility.Converter.GetBytes(hashCode); + if (resourceData.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt) + { + bytes = Utility.Encryption.GetQuickXorBytes(bytes, hashBytes); + } + else if (resourceData.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + bytes = Utility.Encryption.GetXorBytes(bytes, hashBytes); + } + + return ProcessOutput(platform, outputPackagePath, outputFullPath, outputPackedPath, additionalCompressionSelected, name, variant, fileSystem, resourceData, bytes, length, hashCode, compressedLength, compressedHashCode); + } + + private void ProcessPackageVersionList(string outputPackagePath, Platform platform) + { + Asset[] originalAssets = m_ResourceCollection.GetAssets(); + PackageVersionList.Asset[] assets = new PackageVersionList.Asset[originalAssets.Length]; + for (int i = 0; i < assets.Length; i++) + { + Asset originalAsset = originalAssets[i]; + assets[i] = new PackageVersionList.Asset(originalAsset.Name, GetDependencyAssetIndexes(originalAsset.Name)); + } + + SortedDictionary.ValueCollection resourceDatas = m_ResourceDatas.Values; + + int index = 0; + PackageVersionList.Resource[] resources = new PackageVersionList.Resource[m_ResourceCollection.ResourceCount]; + foreach (ResourceData resourceData in resourceDatas) + { + ResourceCode resourceCode = resourceData.GetCode(platform); + resources[index++] = new PackageVersionList.Resource(resourceData.Name, resourceData.Variant, GetExtension(resourceData), (byte)resourceData.LoadType, resourceCode.Length, resourceCode.HashCode, GetAssetIndexes(resourceData)); + } + + string[] fileSystemNames = GetFileSystemNames(resourceDatas); + PackageVersionList.FileSystem[] fileSystems = new PackageVersionList.FileSystem[fileSystemNames.Length]; + for (int i = 0; i < fileSystems.Length; i++) + { + fileSystems[i] = new PackageVersionList.FileSystem(fileSystemNames[i], GetResourceIndexesFromFileSystem(resourceDatas, fileSystemNames[i])); + } + + string[] resourceGroupNames = GetResourceGroupNames(resourceDatas); + PackageVersionList.ResourceGroup[] resourceGroups = new PackageVersionList.ResourceGroup[resourceGroupNames.Length]; + for (int i = 0; i < resourceGroups.Length; i++) + { + resourceGroups[i] = new PackageVersionList.ResourceGroup(resourceGroupNames[i], GetResourceIndexesFromResourceGroup(resourceDatas, resourceGroupNames[i])); + } + + PackageVersionList versionList = new PackageVersionList(ApplicableGameVersion, InternalResourceVersion, assets, resources, fileSystems, resourceGroups); + PackageVersionListSerializer serializer = new PackageVersionListSerializer(); + serializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.PackageVersionListSerializeCallback_V0); + serializer.RegisterSerializeCallback(1, BuiltinVersionListSerializer.PackageVersionListSerializeCallback_V1); + serializer.RegisterSerializeCallback(2, BuiltinVersionListSerializer.PackageVersionListSerializeCallback_V2); + string packageVersionListPath = Utility.Path.GetRegularPath(Path.Combine(outputPackagePath, RemoteVersionListFileName)); + using (FileStream fileStream = new FileStream(packageVersionListPath, FileMode.Create, FileAccess.Write)) + { + if (!serializer.Serialize(fileStream, versionList)) + { + throw new GameFrameworkException("Serialize package version list failure."); + } + } + } + + private VersionListData ProcessUpdatableVersionList(string outputFullPath, Platform platform) + { + Asset[] originalAssets = m_ResourceCollection.GetAssets(); + UpdatableVersionList.Asset[] assets = new UpdatableVersionList.Asset[originalAssets.Length]; + for (int i = 0; i < assets.Length; i++) + { + Asset originalAsset = originalAssets[i]; + assets[i] = new UpdatableVersionList.Asset(originalAsset.Name, GetDependencyAssetIndexes(originalAsset.Name)); + } + + SortedDictionary.ValueCollection resourceDatas = m_ResourceDatas.Values; + + int index = 0; + UpdatableVersionList.Resource[] resources = new UpdatableVersionList.Resource[m_ResourceCollection.ResourceCount]; + foreach (ResourceData resourceData in resourceDatas) + { + ResourceCode resourceCode = resourceData.GetCode(platform); + resources[index++] = new UpdatableVersionList.Resource(resourceData.Name, resourceData.Variant, GetExtension(resourceData), (byte)resourceData.LoadType, resourceCode.Length, resourceCode.HashCode, resourceCode.CompressedLength, resourceCode.CompressedHashCode, GetAssetIndexes(resourceData)); + } + + string[] fileSystemNames = GetFileSystemNames(resourceDatas); + UpdatableVersionList.FileSystem[] fileSystems = new UpdatableVersionList.FileSystem[fileSystemNames.Length]; + for (int i = 0; i < fileSystems.Length; i++) + { + fileSystems[i] = new UpdatableVersionList.FileSystem(fileSystemNames[i], GetResourceIndexesFromFileSystem(resourceDatas, fileSystemNames[i])); + } + + string[] resourceGroupNames = GetResourceGroupNames(resourceDatas); + UpdatableVersionList.ResourceGroup[] resourceGroups = new UpdatableVersionList.ResourceGroup[resourceGroupNames.Length]; + for (int i = 0; i < resourceGroups.Length; i++) + { + resourceGroups[i] = new UpdatableVersionList.ResourceGroup(resourceGroupNames[i], GetResourceIndexesFromResourceGroup(resourceDatas, resourceGroupNames[i])); + } + + UpdatableVersionList versionList = new UpdatableVersionList(ApplicableGameVersion, InternalResourceVersion, assets, resources, fileSystems, resourceGroups); + UpdatableVersionListSerializer serializer = new UpdatableVersionListSerializer(); + serializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback_V0); + serializer.RegisterSerializeCallback(1, BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback_V1); + serializer.RegisterSerializeCallback(2, BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback_V2); + string updatableVersionListPath = Utility.Path.GetRegularPath(Path.Combine(outputFullPath, RemoteVersionListFileName)); + using (FileStream fileStream = new FileStream(updatableVersionListPath, FileMode.Create, FileAccess.Write)) + { + if (!serializer.Serialize(fileStream, versionList)) + { + throw new GameFrameworkException("Serialize updatable version list failure."); + } + } + + byte[] bytes = File.ReadAllBytes(updatableVersionListPath); + int length = bytes.Length; + int hashCode = Utility.Verifier.GetCrc32(bytes); + bytes = Utility.Compression.Compress(bytes); + int compressedLength = bytes.Length; + File.WriteAllBytes(updatableVersionListPath, bytes); + int compressedHashCode = Utility.Verifier.GetCrc32(bytes); + int dotPosition = RemoteVersionListFileName.LastIndexOf('.'); + string versionListFullNameWithCrc32 = Utility.Text.Format("{0}.{2:x8}.{1}", RemoteVersionListFileName.Substring(0, dotPosition), RemoteVersionListFileName.Substring(dotPosition + 1), hashCode); + string updatableVersionListPathWithCrc32 = Utility.Path.GetRegularPath(Path.Combine(outputFullPath, versionListFullNameWithCrc32)); + File.Move(updatableVersionListPath, updatableVersionListPathWithCrc32); + + return new VersionListData(updatableVersionListPathWithCrc32, length, hashCode, compressedLength, compressedHashCode); + } + + private void ProcessReadOnlyVersionList(string outputPackedPath, Platform platform) + { + ResourceData[] packedResourceDatas = GetPackedResourceDatas(); + + LocalVersionList.Resource[] resources = new LocalVersionList.Resource[packedResourceDatas.Length]; + for (int i = 0; i < resources.Length; i++) + { + ResourceData resourceData = packedResourceDatas[i]; + ResourceCode resourceCode = resourceData.GetCode(platform); + resources[i] = new LocalVersionList.Resource(resourceData.Name, resourceData.Variant, GetExtension(resourceData), (byte)resourceData.LoadType, resourceCode.Length, resourceCode.HashCode); + } + + string[] packedFileSystemNames = GetFileSystemNames(packedResourceDatas); + LocalVersionList.FileSystem[] fileSystems = new LocalVersionList.FileSystem[packedFileSystemNames.Length]; + for (int i = 0; i < fileSystems.Length; i++) + { + fileSystems[i] = new LocalVersionList.FileSystem(packedFileSystemNames[i], GetResourceIndexesFromFileSystem(packedResourceDatas, packedFileSystemNames[i])); + } + + LocalVersionList versionList = new LocalVersionList(resources, fileSystems); + ReadOnlyVersionListSerializer serializer = new ReadOnlyVersionListSerializer(); + serializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V0); + serializer.RegisterSerializeCallback(1, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V1); + serializer.RegisterSerializeCallback(2, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V2); + string readOnlyVersionListPath = Utility.Path.GetRegularPath(Path.Combine(outputPackedPath, LocalVersionListFileName)); + using (FileStream fileStream = new FileStream(readOnlyVersionListPath, FileMode.Create, FileAccess.Write)) + { + if (!serializer.Serialize(fileStream, versionList)) + { + throw new GameFrameworkException("Serialize read-only version list failure."); + } + } + } + + private int[] GetDependencyAssetIndexes(string assetName) + { + List dependencyAssetIndexes = new List(); + Asset[] assets = m_ResourceCollection.GetAssets(); + DependencyData dependencyData = m_ResourceAnalyzerController.GetDependencyData(assetName); + foreach (Asset dependencyAsset in dependencyData.GetDependencyAssets()) + { + for (int i = 0; i < assets.Length; i++) + { + if (assets[i] == dependencyAsset) + { + dependencyAssetIndexes.Add(i); + break; + } + } + } + + dependencyAssetIndexes.Sort(); + return dependencyAssetIndexes.ToArray(); + } + + private int[] GetAssetIndexes(ResourceData resourceData) + { + Asset[] assets = m_ResourceCollection.GetAssets(); + string[] assetGuids = resourceData.GetAssetGuids(); + int[] assetIndexes = new int[assetGuids.Length]; + for (int i = 0; i < assetGuids.Length; i++) + { + assetIndexes[i] = Array.BinarySearch(assets, m_ResourceCollection.GetAsset(assetGuids[i])); + if (assetIndexes[i] < 0) + { + throw new GameFrameworkException("Asset is invalid."); + } + } + + return assetIndexes; + } + + private ResourceData[] GetPackedResourceDatas() + { + List packedResourceDatas = new List(); + foreach (ResourceData resourceData in m_ResourceDatas.Values) + { + if (!resourceData.Packed) + { + continue; + } + + packedResourceDatas.Add(resourceData); + } + + return packedResourceDatas.ToArray(); + } + + private string[] GetFileSystemNames(IEnumerable resourceDatas) + { + HashSet fileSystemNames = new HashSet(); + foreach (ResourceData resourceData in resourceDatas) + { + if (resourceData.FileSystem == null) + { + continue; + } + + fileSystemNames.Add(resourceData.FileSystem); + } + + return fileSystemNames.OrderBy(x => x).ToArray(); + } + + private int[] GetResourceIndexesFromFileSystem(IEnumerable resourceDatas, string fileSystemName) + { + int index = 0; + List resourceIndexes = new List(); + foreach (ResourceData resourceData in resourceDatas) + { + if (resourceData.FileSystem == fileSystemName) + { + resourceIndexes.Add(index); + } + + index++; + } + + resourceIndexes.Sort(); + return resourceIndexes.ToArray(); + } + + private string[] GetResourceGroupNames(IEnumerable resourceDatas) + { + HashSet resourceGroupNames = new HashSet(); + foreach (ResourceData resourceData in resourceDatas) + { + foreach (string resourceGroup in resourceData.GetResourceGroups()) + { + resourceGroupNames.Add(resourceGroup); + } + } + + return resourceGroupNames.OrderBy(x => x).ToArray(); + } + + private int[] GetResourceIndexesFromResourceGroup(IEnumerable resourceDatas, string resourceGroupName) + { + int index = 0; + List resourceIndexes = new List(); + foreach (ResourceData resourceData in resourceDatas) + { + foreach (string resourceGroup in resourceData.GetResourceGroups()) + { + if (resourceGroup == resourceGroupName) + { + resourceIndexes.Add(index); + break; + } + } + + index++; + } + + resourceIndexes.Sort(); + return resourceIndexes.ToArray(); + } + + private void CreateFileSystems(IEnumerable resourceDatas, string outputPath, Dictionary outputFileSystem) + { + outputFileSystem.Clear(); + string[] fileSystemNames = GetFileSystemNames(resourceDatas); + if (fileSystemNames.Length > 0 && m_FileSystemManager == null) + { + m_FileSystemManager = GameFrameworkEntry.GetModule(); + m_FileSystemManager.SetFileSystemHelper(new FileSystemHelper()); + } + + foreach (string fileSystemName in fileSystemNames) + { + int fileCount = GetResourceIndexesFromFileSystem(resourceDatas, fileSystemName).Length; + string fullPath = Utility.Path.GetRegularPath(Path.Combine(outputPath, Utility.Text.Format("{0}.{1}", fileSystemName, DefaultExtension))); + string directory = Path.GetDirectoryName(fullPath); + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + IFileSystem fileSystem = m_FileSystemManager.CreateFileSystem(fullPath, FileSystemAccess.Write, fileCount, fileCount); + outputFileSystem.Add(fileSystemName, fileSystem); + } + } + + private bool ProcessOutput(Platform platform, string outputPackagePath, string outputFullPath, string outputPackedPath, bool additionalCompressionSelected, string name, string variant, string fileSystem, ResourceData resourceData, byte[] bytes, int length, int hashCode, int compressedLength, int compressedHashCode) + { + string fullNameWithExtension = Utility.Text.Format("{0}.{1}", GetResourceFullName(name, variant), GetExtension(resourceData)); + + if (OutputPackageSelected) + { + if (string.IsNullOrEmpty(fileSystem)) + { + string packagePath = Utility.Path.GetRegularPath(Path.Combine(outputPackagePath, fullNameWithExtension)); + string packageDirectoryName = Path.GetDirectoryName(packagePath); + if (!Directory.Exists(packageDirectoryName)) + { + Directory.CreateDirectory(packageDirectoryName); + } + + File.WriteAllBytes(packagePath, bytes); + } + else + { + if (!m_OutputPackageFileSystems[fileSystem].WriteFile(fullNameWithExtension, bytes)) + { + return false; + } + } + } + + if (OutputPackedSelected && resourceData.Packed) + { + if (string.IsNullOrEmpty(fileSystem)) + { + string packedPath = Utility.Path.GetRegularPath(Path.Combine(outputPackedPath, fullNameWithExtension)); + string packedDirectoryName = Path.GetDirectoryName(packedPath); + if (!Directory.Exists(packedDirectoryName)) + { + Directory.CreateDirectory(packedDirectoryName); + } + + File.WriteAllBytes(packedPath, bytes); + } + else + { + if (!m_OutputPackedFileSystems[fileSystem].WriteFile(fullNameWithExtension, bytes)) + { + return false; + } + } + } + + if (OutputFullSelected) + { + string fullNameWithCrc32AndExtension = variant != null ? Utility.Text.Format("{0}.{1}.{2:x8}.{3}", name, variant, hashCode, DefaultExtension) : Utility.Text.Format("{0}.{1:x8}.{2}", name, hashCode, DefaultExtension); + string fullPath = Utility.Path.GetRegularPath(Path.Combine(outputFullPath, fullNameWithCrc32AndExtension)); + string fullDirectoryName = Path.GetDirectoryName(fullPath); + if (!Directory.Exists(fullDirectoryName)) + { + Directory.CreateDirectory(fullDirectoryName); + } + + if (additionalCompressionSelected) + { + byte[] compressedBytes = Utility.Compression.Compress(bytes); + compressedLength = compressedBytes.Length; + compressedHashCode = Utility.Verifier.GetCrc32(compressedBytes); + File.WriteAllBytes(fullPath, compressedBytes); + } + else + { + File.WriteAllBytes(fullPath, bytes); + } + } + + resourceData.AddCode(platform, length, hashCode, compressedLength, compressedHashCode); + return true; + } + + private BuildAssetBundleOptions GetBuildAssetBundleOptions() + { + BuildAssetBundleOptions buildOptions = BuildAssetBundleOptions.None; + + if (ForceRebuildAssetBundleSelected) + { + buildOptions |= BuildAssetBundleOptions.ForceRebuildAssetBundle; + } + + if (AssetBundleCompression == AssetBundleCompressionType.Uncompressed) + { + buildOptions |= BuildAssetBundleOptions.UncompressedAssetBundle; + } + else if (AssetBundleCompression == AssetBundleCompressionType.LZ4) + { + buildOptions |= BuildAssetBundleOptions.ChunkBasedCompression; + } + + return buildOptions; + } + + private bool PrepareBuildData(out AssetBundleBuild[] assetBundleBuildDatas, out ResourceData[] assetBundleResourceDatas, out ResourceData[] binaryResourceDatas) + { + assetBundleBuildDatas = null; + assetBundleResourceDatas = null; + binaryResourceDatas = null; + m_ResourceDatas.Clear(); + + Resource[] resources = m_ResourceCollection.GetResources(); + foreach (Resource resource in resources) + { + m_ResourceDatas.Add(resource.FullName, new ResourceData(resource.Name, resource.Variant, resource.FileSystem, resource.LoadType, resource.Packed, resource.GetResourceGroups())); + } + + Asset[] assets = m_ResourceCollection.GetAssets(); + foreach (Asset asset in assets) + { + string assetName = asset.Name; + if (string.IsNullOrEmpty(assetName)) + { + m_BuildReport.LogError("Can not find asset by guid '{0}'.", asset.Guid); + return false; + } + + string assetFileFullName = Application.dataPath.Substring(0, Application.dataPath.Length - AssetsStringLength) + assetName; + if (!File.Exists(assetFileFullName)) + { + m_BuildReport.LogError("Can not find asset '{0}'.", assetFileFullName); + return false; + } + + byte[] assetBytes = File.ReadAllBytes(assetFileFullName); + int assetHashCode = Utility.Verifier.GetCrc32(assetBytes); + + List dependencyAssetNames = new List(); + DependencyData dependencyData = m_ResourceAnalyzerController.GetDependencyData(assetName); + Asset[] dependencyAssets = dependencyData.GetDependencyAssets(); + foreach (Asset dependencyAsset in dependencyAssets) + { + dependencyAssetNames.Add(dependencyAsset.Name); + } + + dependencyAssetNames.Sort(); + + m_ResourceDatas[asset.Resource.FullName].AddAssetData(asset.Guid, assetName, assetBytes.Length, assetHashCode, dependencyAssetNames.ToArray()); + } + + List assetBundleBuildDataList = new List(); + List assetBundleResourceDataList = new List(); + List binaryResourceDataList = new List(); + foreach (ResourceData resourceData in m_ResourceDatas.Values) + { + if (resourceData.AssetCount <= 0) + { + m_BuildReport.LogError("Resource '{0}' has no asset.", GetResourceFullName(resourceData.Name, resourceData.Variant)); + return false; + } + + if (resourceData.IsLoadFromBinary) + { + binaryResourceDataList.Add(resourceData); + } + else + { + assetBundleResourceDataList.Add(resourceData); + + AssetBundleBuild build = new AssetBundleBuild(); + build.assetBundleName = resourceData.Name; + build.assetBundleVariant = resourceData.Variant; + build.assetNames = resourceData.GetAssetNames(); + assetBundleBuildDataList.Add(build); + } + } + + assetBundleBuildDatas = assetBundleBuildDataList.ToArray(); + assetBundleResourceDatas = assetBundleResourceDataList.ToArray(); + binaryResourceDatas = binaryResourceDataList.ToArray(); + return true; + } + + private static string GetResourceFullName(string name, string variant) + { + return !string.IsNullOrEmpty(variant) ? Utility.Text.Format("{0}.{1}", name, variant) : name; + } + + private static BuildTarget GetBuildTarget(Platform platform) + { + switch (platform) + { + case Platform.Windows: + return BuildTarget.StandaloneWindows; + + case Platform.Windows64: + return BuildTarget.StandaloneWindows64; + + case Platform.MacOS: +#if UNITY_2017_3_OR_NEWER + return BuildTarget.StandaloneOSX; +#else + return BuildTarget.StandaloneOSXUniversal; +#endif + case Platform.Linux: + return BuildTarget.StandaloneLinux64; + + case Platform.IOS: + return BuildTarget.iOS; + + case Platform.Android: + return BuildTarget.Android; + + case Platform.WindowsStore: + return BuildTarget.WSAPlayer; + + case Platform.WebGL: + return BuildTarget.WebGL; + + default: + throw new GameFrameworkException("Platform is invalid."); + } + } + + private static string GetExtension(ResourceData data) + { + if (data.IsLoadFromBinary) + { + string assetName = data.GetAssetNames()[0]; + int position = assetName.LastIndexOf('.'); + if (position >= 0) + { + return assetName.Substring(position + 1); + } + } + + return DefaultExtension; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.cs.meta new file mode 100644 index 0000000..4bd0398 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceBuilder/ResourceBuilderController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2678da0502f5874429b8bce3d35f573f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection.meta new file mode 100644 index 0000000..80df7f1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bc804e13da19ff043aac07751e249b43 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Asset.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Asset.cs new file mode 100644 index 0000000..fa7c54c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Asset.cs @@ -0,0 +1,59 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using UnityEditor; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源。 + /// + public sealed class Asset : IComparable + { + private Asset(string guid, Resource resource) + { + Guid = guid; + Resource = resource; + } + + public string Guid + { + get; + private set; + } + + public string Name + { + get + { + return AssetDatabase.GUIDToAssetPath(Guid); + } + } + + public Resource Resource + { + get; + set; + } + + public int CompareTo(Asset asset) + { + return string.Compare(Guid, asset.Guid, StringComparison.Ordinal); + } + + public static Asset Create(string guid) + { + return new Asset(guid, null); + } + + public static Asset Create(string guid, Resource resource) + { + return new Asset(guid, resource); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Asset.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Asset.cs.meta new file mode 100644 index 0000000..c983873 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Asset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0147356ab2aa7548b5448288d785afe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/AssetType.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/AssetType.cs new file mode 100644 index 0000000..1259b6c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/AssetType.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源类型。 + /// + public enum AssetType : byte + { + /// + /// 未知。 + /// + Unknown = 0, + + /// + /// 存放资源。 + /// + Asset, + + /// + /// 存放场景。 + /// + Scene, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/AssetType.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/AssetType.cs.meta new file mode 100644 index 0000000..ead3459 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/AssetType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca96b555ae5b2c34e8cc830446f11525 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/LoadType.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/LoadType.cs new file mode 100644 index 0000000..8cec7db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/LoadType.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源加载方式类型。 + /// + public enum LoadType : byte + { + /// + /// 使用文件方式加载。 + /// + LoadFromFile = 0, + + /// + /// 使用内存方式加载。 + /// + LoadFromMemory, + + /// + /// 使用内存快速解密方式加载。 + /// + LoadFromMemoryAndQuickDecrypt, + + /// + /// 使用内存解密方式加载。 + /// + LoadFromMemoryAndDecrypt, + + /// + /// 使用二进制方式加载。 + /// + LoadFromBinary, + + /// + /// 使用二进制快速解密方式加载。 + /// + LoadFromBinaryAndQuickDecrypt, + + /// + /// 使用二进制解密方式加载。 + /// + LoadFromBinaryAndDecrypt + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/LoadType.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/LoadType.cs.meta new file mode 100644 index 0000000..df7e038 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/LoadType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f5660cbfaa767b84fbc1ef8799919b26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Resource.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Resource.cs new file mode 100644 index 0000000..04d378e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Resource.cs @@ -0,0 +1,192 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源。 + /// + public sealed class Resource + { + private readonly List m_Assets; + private readonly List m_ResourceGroups; + + private Resource(string name, string variant, string fileSystem, LoadType loadType, bool packed, string[] resourceGroups) + { + m_Assets = new List(); + m_ResourceGroups = new List(); + + Name = name; + Variant = variant; + AssetType = AssetType.Unknown; + FileSystem = fileSystem; + LoadType = loadType; + Packed = packed; + + foreach (string resourceGroup in resourceGroups) + { + AddResourceGroup(resourceGroup); + } + } + + public string Name + { + get; + private set; + } + + public string Variant + { + get; + private set; + } + + public string FullName + { + get + { + return Variant != null ? Utility.Text.Format("{0}.{1}", Name, Variant) : Name; + } + } + + public AssetType AssetType + { + get; + private set; + } + + public bool IsLoadFromBinary + { + get + { + return LoadType == LoadType.LoadFromBinary || LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || LoadType == LoadType.LoadFromBinaryAndDecrypt; + } + } + + public string FileSystem + { + get; + set; + } + + public LoadType LoadType + { + get; + set; + } + + public bool Packed + { + get; + set; + } + + public static Resource Create(string name, string variant, string fileSystem, LoadType loadType, bool packed, string[] resourceGroups) + { + return new Resource(name, variant, fileSystem, loadType, packed, resourceGroups ?? new string[0]); + } + + public Asset[] GetAssets() + { + return m_Assets.ToArray(); + } + + public Asset GetFirstAsset() + { + return m_Assets.Count > 0 ? m_Assets[0] : null; + } + + public void Rename(string name, string variant) + { + Name = name; + Variant = variant; + } + + public void AssignAsset(Asset asset, bool isScene) + { + if (asset.Resource != null) + { + asset.Resource.UnassignAsset(asset); + } + + AssetType = isScene ? AssetType.Scene : AssetType.Asset; + asset.Resource = this; + m_Assets.Add(asset); + m_Assets.Sort(AssetComparer); + } + + public void UnassignAsset(Asset asset) + { + asset.Resource = null; + m_Assets.Remove(asset); + if (m_Assets.Count <= 0) + { + AssetType = AssetType.Unknown; + } + } + + public string[] GetResourceGroups() + { + return m_ResourceGroups.ToArray(); + } + + public bool HasResourceGroup(string resourceGroup) + { + if (string.IsNullOrEmpty(resourceGroup)) + { + return false; + } + + return m_ResourceGroups.Contains(resourceGroup); + } + + public void AddResourceGroup(string resourceGroup) + { + if (string.IsNullOrEmpty(resourceGroup)) + { + return; + } + + if (m_ResourceGroups.Contains(resourceGroup)) + { + return; + } + + m_ResourceGroups.Add(resourceGroup); + m_ResourceGroups.Sort(); + } + + public bool RemoveResourceGroup(string resourceGroup) + { + if (string.IsNullOrEmpty(resourceGroup)) + { + return false; + } + + return m_ResourceGroups.Remove(resourceGroup); + } + + public void Clear() + { + foreach (Asset asset in m_Assets) + { + asset.Resource = null; + } + + m_Assets.Clear(); + m_ResourceGroups.Clear(); + } + + private int AssetComparer(Asset a, Asset b) + { + return a.Guid.CompareTo(b.Guid); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Resource.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Resource.cs.meta new file mode 100644 index 0000000..b4b12ad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/Resource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d3d5c5d16bedc54c976247a6a5b429e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollection.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollection.cs new file mode 100644 index 0000000..75d6bfb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollection.cs @@ -0,0 +1,635 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Xml; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源集合。 + /// + public sealed class ResourceCollection + { + private const string SceneExtension = ".unity"; + private static readonly Regex ResourceNameRegex = new Regex(@"^([A-Za-z0-9\._-]+/)*[A-Za-z0-9\._-]+$"); + private static readonly Regex ResourceVariantRegex = new Regex(@"^[a-z0-9_-]+$"); + + private readonly string m_ConfigurationPath; + private readonly SortedDictionary m_Resources; + private readonly SortedDictionary m_Assets; + + public ResourceCollection() + { + m_ConfigurationPath = Type.GetConfigurationPath() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/ResourceCollection.xml")); + m_Resources = new SortedDictionary(StringComparer.Ordinal); + m_Assets = new SortedDictionary(StringComparer.Ordinal); + } + + public int ResourceCount + { + get + { + return m_Resources.Count; + } + } + + public int AssetCount + { + get + { + return m_Assets.Count; + } + } + + public event GameFrameworkAction OnLoadingResource = null; + + public event GameFrameworkAction OnLoadingAsset = null; + + public event GameFrameworkAction OnLoadCompleted = null; + + public void Clear() + { + m_Resources.Clear(); + m_Assets.Clear(); + } + + public bool Load() + { + Clear(); + + if (!File.Exists(m_ConfigurationPath)) + { + return false; + } + + try + { + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.Load(m_ConfigurationPath); + XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework"); + XmlNode xmlCollection = xmlRoot.SelectSingleNode("ResourceCollection"); + XmlNode xmlResources = xmlCollection.SelectSingleNode("Resources"); + XmlNode xmlAssets = xmlCollection.SelectSingleNode("Assets"); + + XmlNodeList xmlNodeList = null; + XmlNode xmlNode = null; + int count = 0; + + xmlNodeList = xmlResources.ChildNodes; + count = xmlNodeList.Count; + for (int i = 0; i < count; i++) + { + if (OnLoadingResource != null) + { + OnLoadingResource(i, count); + } + + xmlNode = xmlNodeList.Item(i); + if (xmlNode.Name != "Resource") + { + continue; + } + + string name = xmlNode.Attributes.GetNamedItem("Name").Value; + string variant = xmlNode.Attributes.GetNamedItem("Variant") != null ? xmlNode.Attributes.GetNamedItem("Variant").Value : null; + string fileSystem = xmlNode.Attributes.GetNamedItem("FileSystem") != null ? xmlNode.Attributes.GetNamedItem("FileSystem").Value : null; + byte loadType = 0; + if (xmlNode.Attributes.GetNamedItem("LoadType") != null) + { + byte.TryParse(xmlNode.Attributes.GetNamedItem("LoadType").Value, out loadType); + } + + bool packed = false; + if (xmlNode.Attributes.GetNamedItem("Packed") != null) + { + bool.TryParse(xmlNode.Attributes.GetNamedItem("Packed").Value, out packed); + } + + string[] resourceGroups = xmlNode.Attributes.GetNamedItem("ResourceGroups") != null ? xmlNode.Attributes.GetNamedItem("ResourceGroups").Value.Split(',') : null; + if (!AddResource(name, variant, fileSystem, (LoadType)loadType, packed, resourceGroups)) + { + Debug.LogWarning(Utility.Text.Format("Can not add resource '{0}'.", GetResourceFullName(name, variant))); + continue; + } + } + + xmlNodeList = xmlAssets.ChildNodes; + count = xmlNodeList.Count; + for (int i = 0; i < count; i++) + { + if (OnLoadingAsset != null) + { + OnLoadingAsset(i, count); + } + + xmlNode = xmlNodeList.Item(i); + if (xmlNode.Name != "Asset") + { + continue; + } + + string guid = xmlNode.Attributes.GetNamedItem("Guid").Value; + string name = xmlNode.Attributes.GetNamedItem("ResourceName").Value; + string variant = xmlNode.Attributes.GetNamedItem("ResourceVariant") != null ? xmlNode.Attributes.GetNamedItem("ResourceVariant").Value : null; + if (!AssignAsset(guid, name, variant)) + { + Debug.LogWarning(Utility.Text.Format("Can not assign asset '{0}' to resource '{1}'.", guid, GetResourceFullName(name, variant))); + continue; + } + } + + if (OnLoadCompleted != null) + { + OnLoadCompleted(); + } + + return true; + } + catch + { + File.Delete(m_ConfigurationPath); + if (OnLoadCompleted != null) + { + OnLoadCompleted(); + } + + return false; + } + } + + public bool Save() + { + try + { + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.AppendChild(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null)); + + XmlElement xmlRoot = xmlDocument.CreateElement("UnityGameFramework"); + xmlDocument.AppendChild(xmlRoot); + + XmlElement xmlCollection = xmlDocument.CreateElement("ResourceCollection"); + xmlRoot.AppendChild(xmlCollection); + + XmlElement xmlResources = xmlDocument.CreateElement("Resources"); + xmlCollection.AppendChild(xmlResources); + + XmlElement xmlAssets = xmlDocument.CreateElement("Assets"); + xmlCollection.AppendChild(xmlAssets); + + XmlElement xmlElement = null; + XmlAttribute xmlAttribute = null; + + foreach (Resource resource in m_Resources.Values) + { + xmlElement = xmlDocument.CreateElement("Resource"); + xmlAttribute = xmlDocument.CreateAttribute("Name"); + xmlAttribute.Value = resource.Name; + xmlElement.Attributes.SetNamedItem(xmlAttribute); + + if (resource.Variant != null) + { + xmlAttribute = xmlDocument.CreateAttribute("Variant"); + xmlAttribute.Value = resource.Variant; + xmlElement.Attributes.SetNamedItem(xmlAttribute); + } + + if (resource.FileSystem != null) + { + xmlAttribute = xmlDocument.CreateAttribute("FileSystem"); + xmlAttribute.Value = resource.FileSystem; + xmlElement.Attributes.SetNamedItem(xmlAttribute); + } + + xmlAttribute = xmlDocument.CreateAttribute("LoadType"); + xmlAttribute.Value = ((byte)resource.LoadType).ToString(); + xmlElement.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("Packed"); + xmlAttribute.Value = resource.Packed.ToString(); + xmlElement.Attributes.SetNamedItem(xmlAttribute); + string[] resourceGroups = resource.GetResourceGroups(); + if (resourceGroups.Length > 0) + { + xmlAttribute = xmlDocument.CreateAttribute("ResourceGroups"); + xmlAttribute.Value = string.Join(",", resourceGroups); + xmlElement.Attributes.SetNamedItem(xmlAttribute); + } + + xmlResources.AppendChild(xmlElement); + } + + foreach (Asset asset in m_Assets.Values) + { + xmlElement = xmlDocument.CreateElement("Asset"); + xmlAttribute = xmlDocument.CreateAttribute("Guid"); + xmlAttribute.Value = asset.Guid; + xmlElement.Attributes.SetNamedItem(xmlAttribute); + xmlAttribute = xmlDocument.CreateAttribute("ResourceName"); + xmlAttribute.Value = asset.Resource.Name; + xmlElement.Attributes.SetNamedItem(xmlAttribute); + if (asset.Resource.Variant != null) + { + xmlAttribute = xmlDocument.CreateAttribute("ResourceVariant"); + xmlAttribute.Value = asset.Resource.Variant; + xmlElement.Attributes.SetNamedItem(xmlAttribute); + } + + xmlAssets.AppendChild(xmlElement); + } + + string configurationDirectoryName = Path.GetDirectoryName(m_ConfigurationPath); + if (!Directory.Exists(configurationDirectoryName)) + { + Directory.CreateDirectory(configurationDirectoryName); + } + + xmlDocument.Save(m_ConfigurationPath); + AssetDatabase.Refresh(); + return true; + } + catch + { + if (File.Exists(m_ConfigurationPath)) + { + File.Delete(m_ConfigurationPath); + } + + return false; + } + } + + public Resource[] GetResources() + { + return m_Resources.Values.ToArray(); + } + + public Resource GetResource(string name, string variant) + { + if (!IsValidResourceName(name, variant)) + { + return null; + } + + Resource resource = null; + if (m_Resources.TryGetValue(GetResourceFullName(name, variant).ToLowerInvariant(), out resource)) + { + return resource; + } + + return null; + } + + public bool HasResource(string name, string variant) + { + if (!IsValidResourceName(name, variant)) + { + return false; + } + + return m_Resources.ContainsKey(GetResourceFullName(name, variant).ToLowerInvariant()); + } + + public bool AddResource(string name, string variant, string fileSystem, LoadType loadType, bool packed) + { + return AddResource(name, variant, fileSystem, loadType, packed, null); + } + + public bool AddResource(string name, string variant, string fileSystem, LoadType loadType, bool packed, string[] resourceGroups) + { + if (!IsValidResourceName(name, variant)) + { + return false; + } + + if (!IsAvailableResourceName(name, variant, null)) + { + return false; + } + + if (fileSystem != null && !ResourceNameRegex.IsMatch(fileSystem)) + { + return false; + } + + Resource resource = Resource.Create(name, variant, fileSystem, loadType, packed, resourceGroups); + m_Resources.Add(resource.FullName.ToLowerInvariant(), resource); + + return true; + } + + public bool RenameResource(string oldName, string oldVariant, string newName, string newVariant) + { + if (!IsValidResourceName(oldName, oldVariant) || !IsValidResourceName(newName, newVariant)) + { + return false; + } + + Resource resource = GetResource(oldName, oldVariant); + if (resource == null) + { + return false; + } + + if (oldName == newName && oldVariant == newVariant) + { + return true; + } + + if (!IsAvailableResourceName(newName, newVariant, resource)) + { + return false; + } + + m_Resources.Remove(resource.FullName.ToLowerInvariant()); + resource.Rename(newName, newVariant); + m_Resources.Add(resource.FullName.ToLowerInvariant(), resource); + + return true; + } + + public bool RemoveResource(string name, string variant) + { + if (!IsValidResourceName(name, variant)) + { + return false; + } + + Resource resource = GetResource(name, variant); + if (resource == null) + { + return false; + } + + Asset[] assets = resource.GetAssets(); + resource.Clear(); + m_Resources.Remove(resource.FullName.ToLowerInvariant()); + foreach (Asset asset in assets) + { + m_Assets.Remove(asset.Guid); + } + + return true; + } + + public bool SetResourceLoadType(string name, string variant, LoadType loadType) + { + if (!IsValidResourceName(name, variant)) + { + return false; + } + + Resource resource = GetResource(name, variant); + if (resource == null) + { + return false; + } + + if ((loadType == LoadType.LoadFromBinary || loadType == LoadType.LoadFromBinaryAndQuickDecrypt || loadType == LoadType.LoadFromBinaryAndDecrypt) && resource.GetAssets().Length > 1) + { + return false; + } + + resource.LoadType = loadType; + return true; + } + + public bool SetResourcePacked(string name, string variant, bool packed) + { + if (!IsValidResourceName(name, variant)) + { + return false; + } + + Resource resource = GetResource(name, variant); + if (resource == null) + { + return false; + } + + resource.Packed = packed; + return true; + } + + public Asset[] GetAssets() + { + return m_Assets.Values.ToArray(); + } + + public Asset[] GetAssets(string name, string variant) + { + if (!IsValidResourceName(name, variant)) + { + return new Asset[0]; + } + + Resource resource = GetResource(name, variant); + if (resource == null) + { + return new Asset[0]; + } + + return resource.GetAssets(); + } + + public Asset GetAsset(string guid) + { + if (string.IsNullOrEmpty(guid)) + { + return null; + } + + Asset asset = null; + if (m_Assets.TryGetValue(guid, out asset)) + { + return asset; + } + + return null; + } + + public bool HasAsset(string guid) + { + if (string.IsNullOrEmpty(guid)) + { + return false; + } + + return m_Assets.ContainsKey(guid); + } + + public bool AssignAsset(string guid, string name, string variant) + { + if (string.IsNullOrEmpty(guid)) + { + return false; + } + + if (!IsValidResourceName(name, variant)) + { + return false; + } + + Resource resource = GetResource(name, variant); + if (resource == null) + { + return false; + } + + string assetName = AssetDatabase.GUIDToAssetPath(guid); + if (string.IsNullOrEmpty(assetName)) + { + return false; + } + + Asset[] assetsInResource = resource.GetAssets(); + foreach (Asset assetInResource in assetsInResource) + { + if (assetInResource.Name == assetName) + { + continue; + } + + if (assetInResource.Name.ToLowerInvariant() == assetName.ToLowerInvariant()) + { + return false; + } + } + + bool isScene = assetName.EndsWith(SceneExtension, StringComparison.Ordinal); + if (isScene && resource.AssetType == AssetType.Asset || !isScene && resource.AssetType == AssetType.Scene) + { + return false; + } + + Asset asset = GetAsset(guid); + if (resource.IsLoadFromBinary && assetsInResource.Length > 0 && asset != assetsInResource[0]) + { + return false; + } + + if (asset == null) + { + asset = Asset.Create(guid); + m_Assets.Add(asset.Guid, asset); + } + + resource.AssignAsset(asset, isScene); + + return true; + } + + public bool UnassignAsset(string guid) + { + if (string.IsNullOrEmpty(guid)) + { + return false; + } + + Asset asset = GetAsset(guid); + if (asset != null) + { + asset.Resource.UnassignAsset(asset); + m_Assets.Remove(asset.Guid); + } + + return true; + } + + private string GetResourceFullName(string name, string variant) + { + return !string.IsNullOrEmpty(variant) ? Utility.Text.Format("{0}.{1}", name, variant) : name; + } + + private bool IsValidResourceName(string name, string variant) + { + if (string.IsNullOrEmpty(name)) + { + return false; + } + + if (!ResourceNameRegex.IsMatch(name)) + { + return false; + } + + if (variant != null && !ResourceVariantRegex.IsMatch(variant)) + { + return false; + } + + return true; + } + + private bool IsAvailableResourceName(string name, string variant, Resource current) + { + Resource found = GetResource(name, variant); + if (found != null && found != current) + { + return false; + } + + string[] foundPathNames = name.Split('/'); + foreach (Resource resource in m_Resources.Values) + { + if (current != null && resource == current) + { + continue; + } + + if (resource.Name == name) + { + if (resource.Variant == null && variant != null) + { + return false; + } + + if (resource.Variant != null && variant == null) + { + return false; + } + } + + if (resource.Name.Length > name.Length + && resource.Name.IndexOf(name, StringComparison.CurrentCultureIgnoreCase) == 0 + && resource.Name[name.Length] == '/') + { + return false; + } + + if (name.Length > resource.Name.Length + && name.IndexOf(resource.Name, StringComparison.CurrentCultureIgnoreCase) == 0 + && name[resource.Name.Length] == '/') + { + return false; + } + + string[] pathNames = resource.Name.Split('/'); + for (int i = 0; i < foundPathNames.Length - 1 && i < pathNames.Length - 1; i++) + { + if (foundPathNames[i].ToLowerInvariant() != pathNames[i].ToLowerInvariant()) + { + break; + } + + if (foundPathNames[i] != pathNames[i]) + { + return false; + } + } + } + + return true; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollection.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollection.cs.meta new file mode 100644 index 0000000..f79b8dd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1736b422b0ea4c46bbaf798d320e6f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollectionConfigPathAttribute.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollectionConfigPathAttribute.cs new file mode 100644 index 0000000..cfcdbdf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollectionConfigPathAttribute.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// ResourceCollection 配置路径属性。 + /// + public sealed class ResourceCollectionConfigPathAttribute : ConfigPathAttribute + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollectionConfigPathAttribute.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollectionConfigPathAttribute.cs.meta new file mode 100644 index 0000000..570a125 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceCollection/ResourceCollectionConfigPathAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1eb3245545d87064b814268034cc7af6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor.meta new file mode 100644 index 0000000..c910193 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8e537bb30b04ebc41bd7575567444988 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/AssetSorterType.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/AssetSorterType.cs new file mode 100644 index 0000000..c8aafd7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/AssetSorterType.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + public enum AssetSorterType : byte + { + Path, + Name, + Guid, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/AssetSorterType.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/AssetSorterType.cs.meta new file mode 100644 index 0000000..bfa9ba5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/AssetSorterType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5463b22a6a4019146a38f7b80dbe6fa7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.MenuState.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.MenuState.cs new file mode 100644 index 0000000..2692310 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.MenuState.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEditor; + +namespace UnityGameFramework.Editor.ResourceTools +{ + internal sealed partial class ResourceEditor : EditorWindow + { + private enum MenuState : byte + { + Normal, + Add, + Rename, + Remove, + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.MenuState.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.MenuState.cs.meta new file mode 100644 index 0000000..70df25a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.MenuState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32b00a6c44b75494f8576b42717b1f1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceFolder.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceFolder.cs new file mode 100644 index 0000000..98b2c69 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceFolder.cs @@ -0,0 +1,164 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + internal sealed partial class ResourceEditor : EditorWindow + { + private sealed class ResourceFolder + { + private static Texture s_CachedIcon = null; + + private readonly List m_Folders; + private readonly List m_Items; + + public ResourceFolder(string name, ResourceFolder folder) + { + m_Folders = new List(); + m_Items = new List(); + + Name = name; + Folder = folder; + } + + public string Name + { + get; + private set; + } + + public ResourceFolder Folder + { + get; + private set; + } + + public string FromRootPath + { + get + { + return Folder == null ? string.Empty : (Folder.Folder == null ? Name : Utility.Text.Format("{0}/{1}", Folder.FromRootPath, Name)); + } + } + + public int Depth + { + get + { + return Folder != null ? Folder.Depth + 1 : 0; + } + } + + public static Texture Icon + { + get + { + if (s_CachedIcon == null) + { + s_CachedIcon = AssetDatabase.GetCachedIcon("Assets"); + } + + return s_CachedIcon; + } + } + + public void Clear() + { + m_Folders.Clear(); + m_Items.Clear(); + } + + public ResourceFolder[] GetFolders() + { + return m_Folders.ToArray(); + } + + public ResourceFolder GetFolder(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Resource folder name is invalid."); + } + + foreach (ResourceFolder folder in m_Folders) + { + if (folder.Name == name) + { + return folder; + } + } + + return null; + } + + public ResourceFolder AddFolder(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Resource folder name is invalid."); + } + + ResourceFolder folder = GetFolder(name); + if (folder != null) + { + throw new GameFrameworkException("Resource folder is already exist."); + } + + folder = new ResourceFolder(name, this); + m_Folders.Add(folder); + + return folder; + } + + public ResourceItem[] GetItems() + { + return m_Items.ToArray(); + } + + public ResourceItem GetItem(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Resource item name is invalid."); + } + + foreach (ResourceItem item in m_Items) + { + if (item.Name == name) + { + return item; + } + } + + return null; + } + + public void AddItem(string name, Resource resource) + { + ResourceItem item = GetItem(name); + if (item != null) + { + throw new GameFrameworkException("Resource item is already exist."); + } + + item = new ResourceItem(name, resource, this); + m_Items.Add(item); + m_Items.Sort(ResourceItemComparer); + } + + private int ResourceItemComparer(ResourceItem a, ResourceItem b) + { + return a.Name.CompareTo(b.Name); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceFolder.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceFolder.cs.meta new file mode 100644 index 0000000..04868b9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceFolder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8cb7e55dc8f5c0b4c8bdad2802a24162 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceItem.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceItem.cs new file mode 100644 index 0000000..d293444 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceItem.cs @@ -0,0 +1,159 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + internal sealed partial class ResourceEditor : EditorWindow + { + private sealed class ResourceItem + { + private static Texture s_CachedUnknownIcon = null; + private static Texture s_CachedAssetIcon = null; + private static Texture s_CachedSceneIcon = null; + + public ResourceItem(string name, Resource resource, ResourceFolder folder) + { + if (resource == null) + { + throw new GameFrameworkException("Resource is invalid."); + } + + if (folder == null) + { + throw new GameFrameworkException("Resource folder is invalid."); + } + + Name = name; + Resource = resource; + Folder = folder; + } + + public string Name + { + get; + private set; + } + + public Resource Resource + { + get; + private set; + } + + public ResourceFolder Folder + { + get; + private set; + } + + public string FromRootPath + { + get + { + return Folder.Folder == null ? Name : Utility.Text.Format("{0}/{1}", Folder.FromRootPath, Name); + } + } + + public int Depth + { + get + { + return Folder != null ? Folder.Depth + 1 : 0; + } + } + + public Texture Icon + { + get + { + if (Resource.IsLoadFromBinary) + { + Asset asset = Resource.GetFirstAsset(); + if (asset != null) + { + Texture texture = AssetDatabase.GetCachedIcon(AssetDatabase.GUIDToAssetPath(asset.Guid)); + return texture != null ? texture : CachedUnknownIcon; + } + } + else + { + switch (Resource.AssetType) + { + case AssetType.Asset: + return CachedAssetIcon; + + case AssetType.Scene: + return CachedSceneIcon; + } + } + + return CachedUnknownIcon; + } + } + + private static Texture CachedUnknownIcon + { + get + { + if (s_CachedUnknownIcon == null) + { + string iconName = null; +#if UNITY_2018_3_OR_NEWER + iconName = "GameObject Icon"; +#else + iconName = "Prefab Icon"; +#endif + s_CachedUnknownIcon = GetIcon(iconName); + } + + return s_CachedUnknownIcon; + } + } + + private static Texture CachedAssetIcon + { + get + { + if (s_CachedAssetIcon == null) + { + string iconName = null; +#if UNITY_2018_3_OR_NEWER + iconName = "Prefab Icon"; +#else + iconName = "PrefabNormal Icon"; +#endif + s_CachedAssetIcon = GetIcon(iconName); + } + + return s_CachedAssetIcon; + } + } + + private static Texture CachedSceneIcon + { + get + { + if (s_CachedSceneIcon == null) + { + s_CachedSceneIcon = GetIcon("SceneAsset Icon"); + } + + return s_CachedSceneIcon; + } + } + + private static Texture GetIcon(string iconName) + { + return EditorGUIUtility.IconContent(iconName).image; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceItem.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceItem.cs.meta new file mode 100644 index 0000000..352c136 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.ResourceItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f2127e06af00f84294606afa2dfc494 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.cs new file mode 100644 index 0000000..3b56daf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.cs @@ -0,0 +1,1120 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源编辑器。 + /// + internal sealed partial class ResourceEditor : EditorWindow + { + private ResourceEditorController m_Controller = null; + private MenuState m_MenuState = MenuState.Normal; + private Resource m_SelectedResource = null; + private ResourceFolder m_ResourceRoot = null; + private HashSet m_ExpandedResourceFolderNames = null; + private HashSet m_SelectedAssetsInSelectedResource = null; + private HashSet m_ExpandedSourceFolders = null; + private HashSet m_SelectedSourceAssets = null; + private Texture m_MissingSourceAssetIcon = null; + + private HashSet m_CachedSelectedSourceFolders = null; + private HashSet m_CachedUnselectedSourceFolders = null; + private HashSet m_CachedAssignedSourceFolders = null; + private HashSet m_CachedUnassignedSourceFolders = null; + private HashSet m_CachedAssignedSourceAssets = null; + private HashSet m_CachedUnassignedSourceAssets = null; + + private Vector2 m_ResourcesViewScroll = Vector2.zero; + private Vector2 m_ResourceViewScroll = Vector2.zero; + private Vector2 m_SourceAssetsViewScroll = Vector2.zero; + private string m_InputResourceName = null; + private string m_InputResourceVariant = null; + private bool m_HideAssignedSourceAssets = false; + private int m_CurrentResourceContentCount = 0; + private int m_CurrentResourceRowOnDraw = 0; + private int m_CurrentSourceRowOnDraw = 0; + + [MenuItem("Game Framework/Resource Tools/Resource Editor", false, 41)] + private static void Open() + { + ResourceEditor window = GetWindow("Resource Editor", true); + window.minSize = new Vector2(1400f, 600f); + } + + private void OnEnable() + { + m_Controller = new ResourceEditorController(); + m_Controller.OnLoadingResource += OnLoadingResource; + m_Controller.OnLoadingAsset += OnLoadingAsset; + m_Controller.OnLoadCompleted += OnLoadCompleted; + m_Controller.OnAssetAssigned += OnAssetAssigned; + m_Controller.OnAssetUnassigned += OnAssetUnassigned; + + m_MenuState = MenuState.Normal; + m_SelectedResource = null; + m_ResourceRoot = new ResourceFolder("Resources", null); + m_ExpandedResourceFolderNames = new HashSet(); + m_SelectedAssetsInSelectedResource = new HashSet(); + m_ExpandedSourceFolders = new HashSet(); + m_SelectedSourceAssets = new HashSet(); + m_MissingSourceAssetIcon = EditorGUIUtility.IconContent("console.warnicon.sml").image; + + m_CachedSelectedSourceFolders = new HashSet(); + m_CachedUnselectedSourceFolders = new HashSet(); + m_CachedAssignedSourceFolders = new HashSet(); + m_CachedUnassignedSourceFolders = new HashSet(); + m_CachedAssignedSourceAssets = new HashSet(); + m_CachedUnassignedSourceAssets = new HashSet(); + + m_ResourcesViewScroll = Vector2.zero; + m_ResourceViewScroll = Vector2.zero; + m_SourceAssetsViewScroll = Vector2.zero; + m_InputResourceName = null; + m_InputResourceVariant = null; + m_HideAssignedSourceAssets = false; + m_CurrentResourceContentCount = 0; + m_CurrentResourceRowOnDraw = 0; + m_CurrentSourceRowOnDraw = 0; + + if (m_Controller.Load()) + { + Debug.Log("Load configuration success."); + } + else + { + Debug.LogWarning("Load configuration failure."); + } + + EditorUtility.DisplayProgressBar("Prepare Resource Editor", "Processing...", 0f); + RefreshResourceTree(); + EditorUtility.ClearProgressBar(); + } + + private void OnGUI() + { + EditorGUILayout.BeginHorizontal(GUILayout.Width(position.width), GUILayout.Height(position.height)); + { + GUILayout.Space(2f); + EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.25f)); + { + GUILayout.Space(5f); + EditorGUILayout.LabelField(Utility.Text.Format("Resource List ({0})", m_Controller.ResourceCount), EditorStyles.boldLabel); + EditorGUILayout.BeginHorizontal("box", GUILayout.Height(position.height - 52f)); + { + DrawResourcesView(); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Space(5f); + DrawResourcesMenu(); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.25f)); + { + GUILayout.Space(5f); + EditorGUILayout.LabelField(Utility.Text.Format("Resource Content ({0})", m_CurrentResourceContentCount), EditorStyles.boldLabel); + EditorGUILayout.BeginHorizontal("box", GUILayout.Height(position.height - 52f)); + { + DrawResourceView(); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Space(5f); + DrawResourceMenu(); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.5f - 16f)); + { + GUILayout.Space(5f); + EditorGUILayout.LabelField("Asset List", EditorStyles.boldLabel); + EditorGUILayout.BeginHorizontal("box", GUILayout.Height(position.height - 52f)); + { + DrawSourceAssetsView(); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Space(5f); + DrawSourceAssetsMenu(); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + GUILayout.Space(5f); + } + EditorGUILayout.EndHorizontal(); + } + + private void DrawResourcesView() + { + m_CurrentResourceRowOnDraw = 0; + m_ResourcesViewScroll = EditorGUILayout.BeginScrollView(m_ResourcesViewScroll); + { + DrawResourceFolder(m_ResourceRoot); + } + EditorGUILayout.EndScrollView(); + } + + private void DrawResourceFolder(ResourceFolder folder) + { + bool expand = IsExpandedResourceFolder(folder); + EditorGUILayout.BeginHorizontal(); + { +#if UNITY_2019_3_OR_NEWER + bool foldout = EditorGUI.Foldout(new Rect(18f + 14f * folder.Depth, 20f * m_CurrentResourceRowOnDraw + 4f, int.MaxValue, 14f), expand, string.Empty, true); +#else + bool foldout = EditorGUI.Foldout(new Rect(18f + 14f * folder.Depth, 20f * m_CurrentResourceRowOnDraw + 2f, int.MaxValue, 14f), expand, string.Empty, true); +#endif + if (expand != foldout) + { + expand = !expand; + SetExpandedResourceFolder(folder, expand); + } + +#if UNITY_2019_3_OR_NEWER + GUI.DrawTexture(new Rect(32f + 14f * folder.Depth, 20f * m_CurrentResourceRowOnDraw + 3f, 16f, 16f), ResourceFolder.Icon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(44f + 14f * folder.Depth), GUILayout.Height(18f)); +#else + GUI.DrawTexture(new Rect(32f + 14f * folder.Depth, 20f * m_CurrentResourceRowOnDraw + 1f, 16f, 16f), ResourceFolder.Icon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(40f + 14f * folder.Depth), GUILayout.Height(18f)); +#endif + EditorGUILayout.LabelField(folder.Name); + } + EditorGUILayout.EndHorizontal(); + + m_CurrentResourceRowOnDraw++; + + if (expand) + { + foreach (ResourceFolder subFolder in folder.GetFolders()) + { + DrawResourceFolder(subFolder); + } + + foreach (ResourceItem resourceItem in folder.GetItems()) + { + DrawResourceItem(resourceItem); + } + } + } + + private void DrawResourceItem(ResourceItem resourceItem) + { + EditorGUILayout.BeginHorizontal(); + { + string title = resourceItem.Name; + if (resourceItem.Resource.Packed) + { + title = "[Packed] " + title; + } + + float emptySpace = position.width; + if (EditorGUILayout.Toggle(m_SelectedResource == resourceItem.Resource, GUILayout.Width(emptySpace - 12f))) + { + ChangeSelectedResource(resourceItem.Resource); + } + else if (m_SelectedResource == resourceItem.Resource) + { + ChangeSelectedResource(null); + } + + GUILayout.Space(-emptySpace + 24f); +#if UNITY_2019_3_OR_NEWER + GUI.DrawTexture(new Rect(32f + 14f * resourceItem.Depth, 20f * m_CurrentResourceRowOnDraw + 3f, 16f, 16f), resourceItem.Icon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(30f + 14f * resourceItem.Depth), GUILayout.Height(18f)); +#else + GUI.DrawTexture(new Rect(32f + 14f * resourceItem.Depth, 20f * m_CurrentResourceRowOnDraw + 1f, 16f, 16f), resourceItem.Icon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(26f + 14f * resourceItem.Depth), GUILayout.Height(18f)); +#endif + EditorGUILayout.LabelField(title); + } + EditorGUILayout.EndHorizontal(); + m_CurrentResourceRowOnDraw++; + } + + private void DrawResourcesMenu() + { + switch (m_MenuState) + { + case MenuState.Normal: + DrawResourcesMenu_Normal(); + break; + + case MenuState.Add: + DrawResourcesMenu_Add(); + break; + + case MenuState.Rename: + DrawResourcesMenu_Rename(); + break; + + case MenuState.Remove: + DrawResourcesMenu_Remove(); + break; + } + } + + private void DrawResourcesMenu_Normal() + { + if (GUILayout.Button("Add", GUILayout.Width(65f))) + { + m_MenuState = MenuState.Add; + m_InputResourceName = null; + m_InputResourceVariant = null; + GUI.FocusControl(null); + } + EditorGUI.BeginDisabledGroup(m_SelectedResource == null); + { + if (GUILayout.Button("Rename", GUILayout.Width(65f))) + { + m_MenuState = MenuState.Rename; + m_InputResourceName = m_SelectedResource != null ? m_SelectedResource.Name : null; + m_InputResourceVariant = m_SelectedResource != null ? m_SelectedResource.Variant : null; + GUI.FocusControl(null); + } + if (GUILayout.Button("Remove", GUILayout.Width(65f))) + { + m_MenuState = MenuState.Remove; + } + if (m_SelectedResource == null) + { + EditorGUILayout.EnumPopup(LoadType.LoadFromFile); + } + else + { + LoadType loadType = (LoadType)EditorGUILayout.EnumPopup(m_SelectedResource.LoadType); + if (loadType != m_SelectedResource.LoadType) + { + SetResourceLoadType(loadType); + } + } + bool packed = EditorGUILayout.ToggleLeft("Packed", m_SelectedResource != null && m_SelectedResource.Packed, GUILayout.Width(65f)); + if (m_SelectedResource != null && packed != m_SelectedResource.Packed) + { + SetResourcePacked(packed); + } + } + EditorGUI.EndDisabledGroup(); + } + + private void DrawResourcesMenu_Add() + { + GUI.SetNextControlName("NewResourceNameTextField"); + m_InputResourceName = EditorGUILayout.TextField(m_InputResourceName); + GUI.SetNextControlName("NewResourceVariantTextField"); + m_InputResourceVariant = EditorGUILayout.TextField(m_InputResourceVariant, GUILayout.Width(60f)); + + if (GUI.GetNameOfFocusedControl() == "NewResourceNameTextField" || GUI.GetNameOfFocusedControl() == "NewResourceVariantTextField") + { + if (Event.current.isKey && Event.current.keyCode == KeyCode.Return) + { + EditorUtility.DisplayProgressBar("Add Resource", "Processing...", 0f); + AddResource(m_InputResourceName, m_InputResourceVariant, true); + EditorUtility.ClearProgressBar(); + Repaint(); + } + } + + if (GUILayout.Button("Add", GUILayout.Width(50f))) + { + EditorUtility.DisplayProgressBar("Add Resource", "Processing...", 0f); + AddResource(m_InputResourceName, m_InputResourceVariant, true); + EditorUtility.ClearProgressBar(); + } + + if (GUILayout.Button("Back", GUILayout.Width(50f))) + { + m_MenuState = MenuState.Normal; + } + } + + private void DrawResourcesMenu_Rename() + { + if (m_SelectedResource == null) + { + m_MenuState = MenuState.Normal; + return; + } + + GUI.SetNextControlName("RenameResourceNameTextField"); + m_InputResourceName = EditorGUILayout.TextField(m_InputResourceName); + GUI.SetNextControlName("RenameResourceVariantTextField"); + m_InputResourceVariant = EditorGUILayout.TextField(m_InputResourceVariant, GUILayout.Width(60f)); + + if (GUI.GetNameOfFocusedControl() == "RenameResourceNameTextField" || GUI.GetNameOfFocusedControl() == "RenameResourceVariantTextField") + { + if (Event.current.isKey && Event.current.keyCode == KeyCode.Return) + { + EditorUtility.DisplayProgressBar("Rename Resource", "Processing...", 0f); + RenameResource(m_SelectedResource, m_InputResourceName, m_InputResourceVariant); + EditorUtility.ClearProgressBar(); + Repaint(); + } + } + + if (GUILayout.Button("OK", GUILayout.Width(50f))) + { + EditorUtility.DisplayProgressBar("Rename Resource", "Processing...", 0f); + RenameResource(m_SelectedResource, m_InputResourceName, m_InputResourceVariant); + EditorUtility.ClearProgressBar(); + } + + if (GUILayout.Button("Back", GUILayout.Width(50f))) + { + m_MenuState = MenuState.Normal; + } + } + + private void DrawResourcesMenu_Remove() + { + if (m_SelectedResource == null) + { + m_MenuState = MenuState.Normal; + return; + } + + GUILayout.Label(Utility.Text.Format("Remove '{0}' ?", m_SelectedResource.FullName)); + + if (GUILayout.Button("Yes", GUILayout.Width(50f))) + { + EditorUtility.DisplayProgressBar("Remove Resource", "Processing...", 0f); + RemoveResource(); + EditorUtility.ClearProgressBar(); + m_MenuState = MenuState.Normal; + } + + if (GUILayout.Button("No", GUILayout.Width(50f))) + { + m_MenuState = MenuState.Normal; + } + } + + private void DrawResourceView() + { + m_ResourceViewScroll = EditorGUILayout.BeginScrollView(m_ResourceViewScroll); + { + if (m_SelectedResource != null) + { + int index = 0; + Asset[] assets = m_Controller.GetAssets(m_SelectedResource.Name, m_SelectedResource.Variant); + m_CurrentResourceContentCount = assets.Length; + foreach (Asset asset in assets) + { + SourceAsset sourceAsset = m_Controller.GetSourceAsset(asset.Guid); + string assetName = sourceAsset != null ? (m_Controller.AssetSorter == AssetSorterType.Path ? sourceAsset.Path : (m_Controller.AssetSorter == AssetSorterType.Name ? sourceAsset.Name : sourceAsset.Guid)) : asset.Guid; + EditorGUILayout.BeginHorizontal(); + { + float emptySpace = position.width; + bool select = IsSelectedAssetInSelectedResource(asset); + if (select != EditorGUILayout.Toggle(select, GUILayout.Width(emptySpace - 12f))) + { + select = !select; + SetSelectedAssetInSelectedResource(asset, select); + } + + GUILayout.Space(-emptySpace + 24f); +#if UNITY_2019_3_OR_NEWER + GUI.DrawTexture(new Rect(20f, 20f * index++ + 3f, 16f, 16f), sourceAsset != null ? sourceAsset.Icon : m_MissingSourceAssetIcon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(16f), GUILayout.Height(18f)); +#else + GUI.DrawTexture(new Rect(20f, 20f * index++ + 1f, 16f, 16f), sourceAsset != null ? sourceAsset.Icon : m_MissingSourceAssetIcon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(14f), GUILayout.Height(18f)); +#endif + EditorGUILayout.LabelField(assetName); + } + EditorGUILayout.EndHorizontal(); + } + } + else + { + m_CurrentResourceContentCount = 0; + } + } + EditorGUILayout.EndScrollView(); + } + + private void DrawResourceMenu() + { + if (GUILayout.Button("All", GUILayout.Width(50f)) && m_SelectedResource != null) + { + Asset[] assets = m_Controller.GetAssets(m_SelectedResource.Name, m_SelectedResource.Variant); + foreach (Asset asset in assets) + { + SetSelectedAssetInSelectedResource(asset, true); + } + } + if (GUILayout.Button("None", GUILayout.Width(50f))) + { + m_SelectedAssetsInSelectedResource.Clear(); + } + m_Controller.AssetSorter = (AssetSorterType)EditorGUILayout.EnumPopup(m_Controller.AssetSorter, GUILayout.Width(60f)); + GUILayout.Label(string.Empty); + EditorGUI.BeginDisabledGroup(m_SelectedResource == null || m_SelectedAssetsInSelectedResource.Count <= 0); + { + if (GUILayout.Button(Utility.Text.Format("{0} >>", m_SelectedAssetsInSelectedResource.Count), GUILayout.Width(80f))) + { + foreach (Asset asset in m_SelectedAssetsInSelectedResource) + { + UnassignAsset(asset); + } + + m_SelectedAssetsInSelectedResource.Clear(); + } + } + EditorGUI.EndDisabledGroup(); + } + + private void DrawSourceAssetsView() + { + m_CurrentSourceRowOnDraw = 0; + m_SourceAssetsViewScroll = EditorGUILayout.BeginScrollView(m_SourceAssetsViewScroll); + { + DrawSourceFolder(m_Controller.SourceAssetRoot); + } + EditorGUILayout.EndScrollView(); + } + + private void DrawSourceAssetsMenu() + { + HashSet selectedSourceAssets = GetSelectedSourceAssets(); + EditorGUI.BeginDisabledGroup(m_SelectedResource == null || selectedSourceAssets.Count <= 0); + { + if (GUILayout.Button(Utility.Text.Format("<< {0}", selectedSourceAssets.Count), GUILayout.Width(80f))) + { + foreach (SourceAsset sourceAsset in selectedSourceAssets) + { + AssignAsset(sourceAsset, m_SelectedResource); + } + + m_SelectedSourceAssets.Clear(); + m_CachedSelectedSourceFolders.Clear(); + } + } + EditorGUI.EndDisabledGroup(); + EditorGUI.BeginDisabledGroup(selectedSourceAssets.Count <= 0); + { + if (GUILayout.Button(Utility.Text.Format("<<< {0}", selectedSourceAssets.Count), GUILayout.Width(80f))) + { + int index = 0; + int count = selectedSourceAssets.Count; + foreach (SourceAsset sourceAsset in selectedSourceAssets) + { + EditorUtility.DisplayProgressBar("Add Resources", Utility.Text.Format("{0}/{1} processing...", ++index, count), (float)index / count); + int dotIndex = sourceAsset.FromRootPath.IndexOf('.'); + string name = dotIndex > 0 ? sourceAsset.FromRootPath.Substring(0, dotIndex) : sourceAsset.FromRootPath; + AddResource(name, null, false); + Resource resource = m_Controller.GetResource(name, null); + if (resource == null) + { + continue; + } + + AssignAsset(sourceAsset, resource); + } + + EditorUtility.DisplayProgressBar("Add Resources", "Complete processing...", 1f); + RefreshResourceTree(); + EditorUtility.ClearProgressBar(); + m_SelectedSourceAssets.Clear(); + m_CachedSelectedSourceFolders.Clear(); + } + } + EditorGUI.EndDisabledGroup(); + bool hideAssignedSourceAssets = EditorGUILayout.ToggleLeft("Hide Assigned", m_HideAssignedSourceAssets, GUILayout.Width(100f)); + if (hideAssignedSourceAssets != m_HideAssignedSourceAssets) + { + m_HideAssignedSourceAssets = hideAssignedSourceAssets; + m_CachedSelectedSourceFolders.Clear(); + m_CachedUnselectedSourceFolders.Clear(); + m_CachedAssignedSourceFolders.Clear(); + m_CachedUnassignedSourceFolders.Clear(); + } + + GUILayout.Label(string.Empty); + if (GUILayout.Button("Clean", GUILayout.Width(80f))) + { + EditorUtility.DisplayProgressBar("Clean", "Processing...", 0f); + CleanResource(); + EditorUtility.ClearProgressBar(); + } + if (GUILayout.Button("Save", GUILayout.Width(80f))) + { + EditorUtility.DisplayProgressBar("Save", "Processing...", 0f); + SaveConfiguration(); + EditorUtility.ClearProgressBar(); + } + } + + private void DrawSourceFolder(SourceFolder sourceFolder) + { + if (m_HideAssignedSourceAssets && IsAssignedSourceFolder(sourceFolder)) + { + return; + } + + bool expand = IsExpandedSourceFolder(sourceFolder); + EditorGUILayout.BeginHorizontal(); + { + bool select = IsSelectedSourceFolder(sourceFolder); + if (select != EditorGUILayout.Toggle(select, GUILayout.Width(12f + 14f * sourceFolder.Depth))) + { + select = !select; + SetSelectedSourceFolder(sourceFolder, select); + } + + GUILayout.Space(-14f * sourceFolder.Depth); +#if UNITY_2019_3_OR_NEWER + bool foldout = EditorGUI.Foldout(new Rect(18f + 14f * sourceFolder.Depth, 20f * m_CurrentSourceRowOnDraw + 4f, int.MaxValue, 14f), expand, string.Empty, true); +#else + bool foldout = EditorGUI.Foldout(new Rect(18f + 14f * sourceFolder.Depth, 20f * m_CurrentSourceRowOnDraw + 2f, int.MaxValue, 14f), expand, string.Empty, true); +#endif + if (expand != foldout) + { + expand = !expand; + SetExpandedSourceFolder(sourceFolder, expand); + } + +#if UNITY_2019_3_OR_NEWER + GUI.DrawTexture(new Rect(32f + 14f * sourceFolder.Depth, 20f * m_CurrentSourceRowOnDraw + 3f, 16f, 16f), SourceFolder.Icon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(30f + 14f * sourceFolder.Depth), GUILayout.Height(18f)); +#else + GUI.DrawTexture(new Rect(32f + 14f * sourceFolder.Depth, 20f * m_CurrentSourceRowOnDraw + 1f, 16f, 16f), SourceFolder.Icon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(26f + 14f * sourceFolder.Depth), GUILayout.Height(18f)); +#endif + EditorGUILayout.LabelField(sourceFolder.Name); + } + EditorGUILayout.EndHorizontal(); + + m_CurrentSourceRowOnDraw++; + + if (expand) + { + foreach (SourceFolder subSourceFolder in sourceFolder.GetFolders()) + { + DrawSourceFolder(subSourceFolder); + } + + foreach (SourceAsset sourceAsset in sourceFolder.GetAssets()) + { + DrawSourceAsset(sourceAsset); + } + } + } + + private void DrawSourceAsset(SourceAsset sourceAsset) + { + if (m_HideAssignedSourceAssets && IsAssignedSourceAsset(sourceAsset)) + { + return; + } + + EditorGUILayout.BeginHorizontal(); + { + float emptySpace = position.width; + bool select = IsSelectedSourceAsset(sourceAsset); + if (select != EditorGUILayout.Toggle(select, GUILayout.Width(emptySpace - 12f))) + { + select = !select; + SetSelectedSourceAsset(sourceAsset, select); + } + + GUILayout.Space(-emptySpace + 24f); +#if UNITY_2019_3_OR_NEWER + GUI.DrawTexture(new Rect(32f + 14f * sourceAsset.Depth, 20f * m_CurrentSourceRowOnDraw + 3f, 16f, 16f), sourceAsset.Icon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(30f + 14f * sourceAsset.Depth), GUILayout.Height(18f)); +#else + GUI.DrawTexture(new Rect(32f + 14f * sourceAsset.Depth, 20f * m_CurrentSourceRowOnDraw + 1f, 16f, 16f), sourceAsset.Icon); + EditorGUILayout.LabelField(string.Empty, GUILayout.Width(26f + 14f * sourceAsset.Depth), GUILayout.Height(18f)); +#endif + EditorGUILayout.LabelField(sourceAsset.Name); + Asset asset = m_Controller.GetAsset(sourceAsset.Guid); + EditorGUILayout.LabelField(asset != null ? GetResourceFullName(asset.Resource.Name, asset.Resource.Variant) : string.Empty, GUILayout.Width(position.width * 0.15f)); + } + EditorGUILayout.EndHorizontal(); + m_CurrentSourceRowOnDraw++; + } + + private void ChangeSelectedResource(Resource resource) + { + if (m_SelectedResource == resource) + { + return; + } + + m_SelectedResource = resource; + m_SelectedAssetsInSelectedResource.Clear(); + } + + private void SaveConfiguration() + { + if (m_Controller.Save()) + { + Debug.Log("Save configuration success."); + } + else + { + Debug.LogWarning("Save configuration failure."); + } + } + + private void AddResource(string name, string variant, bool refresh) + { + if (variant == string.Empty) + { + variant = null; + } + + string fullName = GetResourceFullName(name, variant); + if (m_Controller.AddResource(name, variant, null, LoadType.LoadFromFile, false)) + { + if (refresh) + { + RefreshResourceTree(); + } + + Debug.Log(Utility.Text.Format("Add resource '{0}' success.", fullName)); + m_MenuState = MenuState.Normal; + } + else + { + Debug.LogWarning(Utility.Text.Format("Add resource '{0}' failure.", fullName)); + } + } + + private void RenameResource(Resource resource, string newName, string newVariant) + { + if (resource == null) + { + Debug.LogWarning("Resource is invalid."); + return; + } + + if (newVariant == string.Empty) + { + newVariant = null; + } + + string oldFullName = resource.FullName; + string newFullName = GetResourceFullName(newName, newVariant); + if (m_Controller.RenameResource(resource.Name, resource.Variant, newName, newVariant)) + { + RefreshResourceTree(); + Debug.Log(Utility.Text.Format("Rename resource '{0}' to '{1}' success.", oldFullName, newFullName)); + m_MenuState = MenuState.Normal; + } + else + { + Debug.LogWarning(Utility.Text.Format("Rename resource '{0}' to '{1}' failure.", oldFullName, newFullName)); + } + } + + private void RemoveResource() + { + string fullName = m_SelectedResource.FullName; + if (m_Controller.RemoveResource(m_SelectedResource.Name, m_SelectedResource.Variant)) + { + ChangeSelectedResource(null); + RefreshResourceTree(); + Debug.Log(Utility.Text.Format("Remove resource '{0}' success.", fullName)); + } + else + { + Debug.LogWarning(Utility.Text.Format("Remove resource '{0}' failure.", fullName)); + } + } + + private void SetResourceLoadType(LoadType loadType) + { + string fullName = m_SelectedResource.FullName; + if (m_Controller.SetResourceLoadType(m_SelectedResource.Name, m_SelectedResource.Variant, loadType)) + { + Debug.Log(Utility.Text.Format("Set resource '{0}' load type to '{1}' success.", fullName, loadType)); + } + else + { + Debug.LogWarning(Utility.Text.Format("Set resource '{0}' load type to '{1}' failure.", fullName, loadType)); + } + } + + private void SetResourcePacked(bool packed) + { + string fullName = m_SelectedResource.FullName; + if (m_Controller.SetResourcePacked(m_SelectedResource.Name, m_SelectedResource.Variant, packed)) + { + Debug.Log(Utility.Text.Format("{1} resource '{0}' success.", fullName, packed ? "Pack" : "Unpack")); + } + else + { + Debug.LogWarning(Utility.Text.Format("{1} resource '{0}' failure.", fullName, packed ? "Pack" : "Unpack")); + } + } + + private void AssignAsset(SourceAsset sourceAsset, Resource resource) + { + if (!m_Controller.AssignAsset(sourceAsset.Guid, resource.Name, resource.Variant)) + { + Debug.LogWarning(Utility.Text.Format("Assign asset '{0}' to resource '{1}' failure.", sourceAsset.Name, resource.FullName)); + } + } + + private void UnassignAsset(Asset asset) + { + if (!m_Controller.UnassignAsset(asset.Guid)) + { + Debug.LogWarning(Utility.Text.Format("Unassign asset '{0}' from resource '{1}' failure.", asset.Guid, m_SelectedResource.FullName)); + } + } + + private void CleanResource() + { + int unknownAssetCount = m_Controller.RemoveUnknownAssets(); + int unusedResourceCount = m_Controller.RemoveUnusedResources(); + RefreshResourceTree(); + + Debug.Log(Utility.Text.Format("Clean complete, {0} unknown assets and {1} unused resources has been removed.", unknownAssetCount, unusedResourceCount)); + } + + private void RefreshResourceTree() + { + m_ResourceRoot.Clear(); + Resource[] resources = m_Controller.GetResources(); + foreach (Resource resource in resources) + { + string[] splitedPath = resource.Name.Split('/'); + ResourceFolder folder = m_ResourceRoot; + for (int i = 0; i < splitedPath.Length - 1; i++) + { + ResourceFolder subFolder = folder.GetFolder(splitedPath[i]); + folder = subFolder == null ? folder.AddFolder(splitedPath[i]) : subFolder; + } + + string fullName = resource.Variant != null ? Utility.Text.Format("{0}.{1}", splitedPath[splitedPath.Length - 1], resource.Variant) : splitedPath[splitedPath.Length - 1]; + folder.AddItem(fullName, resource); + } + } + + private bool IsExpandedResourceFolder(ResourceFolder folder) + { + return m_ExpandedResourceFolderNames.Contains(folder.FromRootPath); + } + + private void SetExpandedResourceFolder(ResourceFolder folder, bool expand) + { + if (expand) + { + m_ExpandedResourceFolderNames.Add(folder.FromRootPath); + } + else + { + m_ExpandedResourceFolderNames.Remove(folder.FromRootPath); + } + } + + private bool IsSelectedAssetInSelectedResource(Asset asset) + { + return m_SelectedAssetsInSelectedResource.Contains(asset); + } + + private void SetSelectedAssetInSelectedResource(Asset asset, bool select) + { + if (select) + { + m_SelectedAssetsInSelectedResource.Add(asset); + } + else + { + m_SelectedAssetsInSelectedResource.Remove(asset); + } + } + + private bool IsExpandedSourceFolder(SourceFolder sourceFolder) + { + return m_ExpandedSourceFolders.Contains(sourceFolder); + } + + private void SetExpandedSourceFolder(SourceFolder sourceFolder, bool expand) + { + if (expand) + { + m_ExpandedSourceFolders.Add(sourceFolder); + } + else + { + m_ExpandedSourceFolders.Remove(sourceFolder); + } + } + + private bool IsSelectedSourceFolder(SourceFolder sourceFolder) + { + if (m_CachedSelectedSourceFolders.Contains(sourceFolder)) + { + return true; + } + + if (m_CachedUnselectedSourceFolders.Contains(sourceFolder)) + { + return false; + } + + foreach (SourceAsset sourceAsset in sourceFolder.GetAssets()) + { + if (m_HideAssignedSourceAssets && IsAssignedSourceAsset(sourceAsset)) + { + continue; + } + + if (!IsSelectedSourceAsset(sourceAsset)) + { + m_CachedUnselectedSourceFolders.Add(sourceFolder); + return false; + } + } + + foreach (SourceFolder subSourceFolder in sourceFolder.GetFolders()) + { + if (m_HideAssignedSourceAssets && IsAssignedSourceFolder(sourceFolder)) + { + continue; + } + + if (!IsSelectedSourceFolder(subSourceFolder)) + { + m_CachedUnselectedSourceFolders.Add(sourceFolder); + return false; + } + } + + m_CachedSelectedSourceFolders.Add(sourceFolder); + return true; + } + + private void SetSelectedSourceFolder(SourceFolder sourceFolder, bool select) + { + if (select) + { + m_CachedSelectedSourceFolders.Add(sourceFolder); + m_CachedUnselectedSourceFolders.Remove(sourceFolder); + + SourceFolder folder = sourceFolder; + while (folder != null) + { + m_CachedUnselectedSourceFolders.Remove(folder); + folder = folder.Folder; + } + } + else + { + m_CachedSelectedSourceFolders.Remove(sourceFolder); + m_CachedUnselectedSourceFolders.Add(sourceFolder); + + SourceFolder folder = sourceFolder; + while (folder != null) + { + m_CachedSelectedSourceFolders.Remove(folder); + folder = folder.Folder; + } + } + + foreach (SourceAsset sourceAsset in sourceFolder.GetAssets()) + { + if (m_HideAssignedSourceAssets && IsAssignedSourceAsset(sourceAsset)) + { + continue; + } + + SetSelectedSourceAsset(sourceAsset, select); + } + + foreach (SourceFolder subSourceFolder in sourceFolder.GetFolders()) + { + if (m_HideAssignedSourceAssets && IsAssignedSourceFolder(subSourceFolder)) + { + continue; + } + + SetSelectedSourceFolder(subSourceFolder, select); + } + } + + private bool IsSelectedSourceAsset(SourceAsset sourceAsset) + { + return m_SelectedSourceAssets.Contains(sourceAsset); + } + + private void SetSelectedSourceAsset(SourceAsset sourceAsset, bool select) + { + if (select) + { + m_SelectedSourceAssets.Add(sourceAsset); + + SourceFolder folder = sourceAsset.Folder; + while (folder != null) + { + m_CachedUnselectedSourceFolders.Remove(folder); + folder = folder.Folder; + } + } + else + { + m_SelectedSourceAssets.Remove(sourceAsset); + + SourceFolder folder = sourceAsset.Folder; + while (folder != null) + { + m_CachedSelectedSourceFolders.Remove(folder); + folder = folder.Folder; + } + } + } + + private bool IsAssignedSourceAsset(SourceAsset sourceAsset) + { + if (m_CachedAssignedSourceAssets.Contains(sourceAsset)) + { + return true; + } + + if (m_CachedUnassignedSourceAssets.Contains(sourceAsset)) + { + return false; + } + + return m_Controller.GetAsset(sourceAsset.Guid) != null; + } + + private bool IsAssignedSourceFolder(SourceFolder sourceFolder) + { + if (m_CachedAssignedSourceFolders.Contains(sourceFolder)) + { + return true; + } + + if (m_CachedUnassignedSourceFolders.Contains(sourceFolder)) + { + return false; + } + + foreach (SourceAsset sourceAsset in sourceFolder.GetAssets()) + { + if (!IsAssignedSourceAsset(sourceAsset)) + { + m_CachedUnassignedSourceFolders.Add(sourceFolder); + return false; + } + } + + foreach (SourceFolder subSourceFolder in sourceFolder.GetFolders()) + { + if (!IsAssignedSourceFolder(subSourceFolder)) + { + m_CachedUnassignedSourceFolders.Add(sourceFolder); + return false; + } + } + + m_CachedAssignedSourceFolders.Add(sourceFolder); + return true; + } + + private HashSet GetSelectedSourceAssets() + { + if (!m_HideAssignedSourceAssets) + { + return m_SelectedSourceAssets; + } + + HashSet selectedUnassignedSourceAssets = new HashSet(); + foreach (SourceAsset sourceAsset in m_SelectedSourceAssets) + { + if (!IsAssignedSourceAsset(sourceAsset)) + { + selectedUnassignedSourceAssets.Add(sourceAsset); + } + } + + return selectedUnassignedSourceAssets; + } + + private string GetResourceFullName(string name, string variant) + { + return variant != null ? Utility.Text.Format("{0}.{1}", name, variant) : name; + } + + private void OnLoadingResource(int index, int count) + { + EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index, count), (float)index / count); + } + + private void OnLoadingAsset(int index, int count) + { + EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index, count), (float)index / count); + } + + private void OnLoadCompleted() + { + EditorUtility.ClearProgressBar(); + } + + private void OnAssetAssigned(SourceAsset[] sourceAssets) + { + HashSet affectedFolders = new HashSet(); + foreach (SourceAsset sourceAsset in sourceAssets) + { + m_CachedAssignedSourceAssets.Add(sourceAsset); + m_CachedUnassignedSourceAssets.Remove(sourceAsset); + + affectedFolders.Add(sourceAsset.Folder); + } + + foreach (SourceFolder sourceFolder in affectedFolders) + { + SourceFolder folder = sourceFolder; + while (folder != null) + { + m_CachedUnassignedSourceFolders.Remove(folder); + folder = folder.Folder; + } + } + } + + private void OnAssetUnassigned(SourceAsset[] sourceAssets) + { + HashSet affectedFolders = new HashSet(); + foreach (SourceAsset sourceAsset in sourceAssets) + { + m_CachedAssignedSourceAssets.Remove(sourceAsset); + m_CachedUnassignedSourceAssets.Add(sourceAsset); + + affectedFolders.Add(sourceAsset.Folder); + } + + foreach (SourceFolder sourceFolder in affectedFolders) + { + SourceFolder folder = sourceFolder; + while (folder != null) + { + m_CachedSelectedSourceFolders.Remove(folder); + m_CachedAssignedSourceFolders.Remove(folder); + m_CachedUnassignedSourceFolders.Add(folder); + folder = folder.Folder; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.cs.meta new file mode 100644 index 0000000..a3dab36 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 956e53f5acdcb4c40a8ecc68d943dde0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorConfigPathAttribute.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorConfigPathAttribute.cs new file mode 100644 index 0000000..fda042c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorConfigPathAttribute.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// ResourceEditor 配置路径属性。 + /// + public sealed class ResourceEditorConfigPathAttribute : ConfigPathAttribute + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorConfigPathAttribute.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorConfigPathAttribute.cs.meta new file mode 100644 index 0000000..0071545 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorConfigPathAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af287b4a1d99d3946b1aab8f70c78964 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorController.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorController.cs new file mode 100644 index 0000000..fb6114b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorController.cs @@ -0,0 +1,679 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed class ResourceEditorController + { + private const string DefaultSourceAssetRootPath = "Assets"; + + private readonly string m_ConfigurationPath; + private readonly ResourceCollection m_ResourceCollection; + private readonly List m_SourceAssetSearchPaths; + private readonly List m_SourceAssetSearchRelativePaths; + private readonly Dictionary m_SourceAssets; + private SourceFolder m_SourceAssetRoot; + private string m_SourceAssetRootPath; + private string m_SourceAssetUnionTypeFilter; + private string m_SourceAssetUnionLabelFilter; + private string m_SourceAssetExceptTypeFilter; + private string m_SourceAssetExceptLabelFilter; + private AssetSorterType m_AssetSorter; + + public ResourceEditorController() + { + m_ConfigurationPath = Type.GetConfigurationPath() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/ResourceEditor.xml")); + m_ResourceCollection = new ResourceCollection(); + m_ResourceCollection.OnLoadingResource += delegate (int index, int count) + { + if (OnLoadingResource != null) + { + OnLoadingResource(index, count); + } + }; + + m_ResourceCollection.OnLoadingAsset += delegate (int index, int count) + { + if (OnLoadingAsset != null) + { + OnLoadingAsset(index, count); + } + }; + + m_ResourceCollection.OnLoadCompleted += delegate () + { + if (OnLoadCompleted != null) + { + OnLoadCompleted(); + } + }; + + m_SourceAssetSearchPaths = new List(); + m_SourceAssetSearchRelativePaths = new List(); + m_SourceAssets = new Dictionary(StringComparer.Ordinal); + m_SourceAssetRoot = null; + m_SourceAssetRootPath = null; + m_SourceAssetUnionTypeFilter = null; + m_SourceAssetUnionLabelFilter = null; + m_SourceAssetExceptTypeFilter = null; + m_SourceAssetExceptLabelFilter = null; + m_AssetSorter = AssetSorterType.Path; + + SourceAssetRootPath = DefaultSourceAssetRootPath; + } + + public int ResourceCount + { + get + { + return m_ResourceCollection.ResourceCount; + } + } + + public int AssetCount + { + get + { + return m_ResourceCollection.AssetCount; + } + } + + public SourceFolder SourceAssetRoot + { + get + { + return m_SourceAssetRoot; + } + } + + public string SourceAssetRootPath + { + get + { + return m_SourceAssetRootPath; + } + set + { + if (m_SourceAssetRootPath == value) + { + return; + } + + m_SourceAssetRootPath = value.Replace('\\', '/'); + m_SourceAssetRoot = new SourceFolder(m_SourceAssetRootPath, null); + RefreshSourceAssetSearchPaths(); + } + } + + public string SourceAssetUnionTypeFilter + { + get + { + return m_SourceAssetUnionTypeFilter; + } + set + { + if (m_SourceAssetUnionTypeFilter == value) + { + return; + } + + m_SourceAssetUnionTypeFilter = value; + } + } + + public string SourceAssetUnionLabelFilter + { + get + { + return m_SourceAssetUnionLabelFilter; + } + set + { + if (m_SourceAssetUnionLabelFilter == value) + { + return; + } + + m_SourceAssetUnionLabelFilter = value; + } + } + + public string SourceAssetExceptTypeFilter + { + get + { + return m_SourceAssetExceptTypeFilter; + } + set + { + if (m_SourceAssetExceptTypeFilter == value) + { + return; + } + + m_SourceAssetExceptTypeFilter = value; + } + } + + public string SourceAssetExceptLabelFilter + { + get + { + return m_SourceAssetExceptLabelFilter; + } + set + { + if (m_SourceAssetExceptLabelFilter == value) + { + return; + } + + m_SourceAssetExceptLabelFilter = value; + } + } + + public AssetSorterType AssetSorter + { + get + { + return m_AssetSorter; + } + set + { + if (m_AssetSorter == value) + { + return; + } + + m_AssetSorter = value; + } + } + + public event GameFrameworkAction OnLoadingResource = null; + + public event GameFrameworkAction OnLoadingAsset = null; + + public event GameFrameworkAction OnLoadCompleted = null; + + public event GameFrameworkAction OnAssetAssigned = null; + + public event GameFrameworkAction OnAssetUnassigned = null; + + public bool Load() + { + if (!File.Exists(m_ConfigurationPath)) + { + return false; + } + + try + { + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.Load(m_ConfigurationPath); + XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework"); + XmlNode xmlEditor = xmlRoot.SelectSingleNode("ResourceEditor"); + XmlNode xmlSettings = xmlEditor.SelectSingleNode("Settings"); + + XmlNodeList xmlNodeList = null; + XmlNode xmlNode = null; + + xmlNodeList = xmlSettings.ChildNodes; + for (int i = 0; i < xmlNodeList.Count; i++) + { + xmlNode = xmlNodeList.Item(i); + switch (xmlNode.Name) + { + case "SourceAssetRootPath": + SourceAssetRootPath = xmlNode.InnerText; + break; + + case "SourceAssetSearchPaths": + m_SourceAssetSearchRelativePaths.Clear(); + XmlNodeList xmlNodeListInner = xmlNode.ChildNodes; + XmlNode xmlNodeInner = null; + for (int j = 0; j < xmlNodeListInner.Count; j++) + { + xmlNodeInner = xmlNodeListInner.Item(j); + if (xmlNodeInner.Name != "SourceAssetSearchPath") + { + continue; + } + + m_SourceAssetSearchRelativePaths.Add(xmlNodeInner.Attributes.GetNamedItem("RelativePath").Value); + } + break; + + case "SourceAssetUnionTypeFilter": + SourceAssetUnionTypeFilter = xmlNode.InnerText; + break; + + case "SourceAssetUnionLabelFilter": + SourceAssetUnionLabelFilter = xmlNode.InnerText; + break; + + case "SourceAssetExceptTypeFilter": + SourceAssetExceptTypeFilter = xmlNode.InnerText; + break; + + case "SourceAssetExceptLabelFilter": + SourceAssetExceptLabelFilter = xmlNode.InnerText; + break; + + case "AssetSorter": + AssetSorter = (AssetSorterType)Enum.Parse(typeof(AssetSorterType), xmlNode.InnerText); + break; + } + } + + RefreshSourceAssetSearchPaths(); + } + catch + { + File.Delete(m_ConfigurationPath); + return false; + } + + ScanSourceAssets(); + + m_ResourceCollection.Load(); + + return true; + } + + public bool Save() + { + try + { + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.AppendChild(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null)); + + XmlElement xmlRoot = xmlDocument.CreateElement("UnityGameFramework"); + xmlDocument.AppendChild(xmlRoot); + + XmlElement xmlEditor = xmlDocument.CreateElement("ResourceEditor"); + xmlRoot.AppendChild(xmlEditor); + + XmlElement xmlSettings = xmlDocument.CreateElement("Settings"); + xmlEditor.AppendChild(xmlSettings); + + XmlElement xmlElement = null; + XmlAttribute xmlAttribute = null; + + xmlElement = xmlDocument.CreateElement("SourceAssetRootPath"); + xmlElement.InnerText = SourceAssetRootPath.ToString(); + xmlSettings.AppendChild(xmlElement); + + xmlElement = xmlDocument.CreateElement("SourceAssetSearchPaths"); + xmlSettings.AppendChild(xmlElement); + + foreach (string sourceAssetSearchRelativePath in m_SourceAssetSearchRelativePaths) + { + XmlElement xmlElementInner = xmlDocument.CreateElement("SourceAssetSearchPath"); + xmlAttribute = xmlDocument.CreateAttribute("RelativePath"); + xmlAttribute.Value = sourceAssetSearchRelativePath; + xmlElementInner.Attributes.SetNamedItem(xmlAttribute); + xmlElement.AppendChild(xmlElementInner); + } + + xmlElement = xmlDocument.CreateElement("SourceAssetUnionTypeFilter"); + xmlElement.InnerText = SourceAssetUnionTypeFilter ?? string.Empty; + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("SourceAssetUnionLabelFilter"); + xmlElement.InnerText = SourceAssetUnionLabelFilter ?? string.Empty; + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("SourceAssetExceptTypeFilter"); + xmlElement.InnerText = SourceAssetExceptTypeFilter ?? string.Empty; + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("SourceAssetExceptLabelFilter"); + xmlElement.InnerText = SourceAssetExceptLabelFilter ?? string.Empty; + xmlSettings.AppendChild(xmlElement); + xmlElement = xmlDocument.CreateElement("AssetSorter"); + xmlElement.InnerText = AssetSorter.ToString(); + xmlSettings.AppendChild(xmlElement); + + string configurationDirectoryName = Path.GetDirectoryName(m_ConfigurationPath); + if (!Directory.Exists(configurationDirectoryName)) + { + Directory.CreateDirectory(configurationDirectoryName); + } + + xmlDocument.Save(m_ConfigurationPath); + AssetDatabase.Refresh(); + } + catch + { + if (File.Exists(m_ConfigurationPath)) + { + File.Delete(m_ConfigurationPath); + } + + return false; + } + + return m_ResourceCollection.Save(); + } + + public Resource[] GetResources() + { + return m_ResourceCollection.GetResources(); + } + + public Resource GetResource(string name, string variant) + { + return m_ResourceCollection.GetResource(name, variant); + } + + public bool HasResource(string name, string variant) + { + return m_ResourceCollection.HasResource(name, variant); + } + + public bool AddResource(string name, string variant, string fileSystem, LoadType loadType, bool packed) + { + return m_ResourceCollection.AddResource(name, variant, fileSystem, loadType, packed); + } + + public bool RenameResource(string oldName, string oldVariant, string newName, string newVariant) + { + return m_ResourceCollection.RenameResource(oldName, oldVariant, newName, newVariant); + } + + public bool RemoveResource(string name, string variant) + { + Asset[] assetsToRemove = m_ResourceCollection.GetAssets(name, variant); + if (m_ResourceCollection.RemoveResource(name, variant)) + { + List unassignedSourceAssets = new List(); + foreach (Asset asset in assetsToRemove) + { + SourceAsset sourceAsset = GetSourceAsset(asset.Guid); + if (sourceAsset != null) + { + unassignedSourceAssets.Add(sourceAsset); + } + } + + if (OnAssetUnassigned != null) + { + OnAssetUnassigned(unassignedSourceAssets.ToArray()); + } + + return true; + } + + return false; + } + + public bool SetResourceLoadType(string name, string variant, LoadType loadType) + { + return m_ResourceCollection.SetResourceLoadType(name, variant, loadType); + } + + public bool SetResourcePacked(string name, string variant, bool packed) + { + return m_ResourceCollection.SetResourcePacked(name, variant, packed); + } + + public int RemoveUnusedResources() + { + List resources = new List(m_ResourceCollection.GetResources()); + List removeResources = resources.FindAll(resource => GetAssets(resource.Name, resource.Variant).Length <= 0); + foreach (Resource removeResource in removeResources) + { + m_ResourceCollection.RemoveResource(removeResource.Name, removeResource.Variant); + } + + return removeResources.Count; + } + + public Asset[] GetAssets(string name, string variant) + { + List assets = new List(m_ResourceCollection.GetAssets(name, variant)); + switch (AssetSorter) + { + case AssetSorterType.Path: + assets.Sort(AssetPathComparer); + break; + + case AssetSorterType.Name: + assets.Sort(AssetNameComparer); + break; + + case AssetSorterType.Guid: + assets.Sort(AssetGuidComparer); + break; + } + + return assets.ToArray(); + } + + public Asset GetAsset(string guid) + { + return m_ResourceCollection.GetAsset(guid); + } + + public bool AssignAsset(string guid, string name, string variant) + { + if (m_ResourceCollection.AssignAsset(guid, name, variant)) + { + if (OnAssetAssigned != null) + { + OnAssetAssigned(new SourceAsset[] { GetSourceAsset(guid) }); + } + + return true; + } + + return false; + } + + public bool UnassignAsset(string guid) + { + if (m_ResourceCollection.UnassignAsset(guid)) + { + SourceAsset sourceAsset = GetSourceAsset(guid); + if (sourceAsset != null) + { + if (OnAssetUnassigned != null) + { + OnAssetUnassigned(new SourceAsset[] { sourceAsset }); + } + } + + return true; + } + + return false; + } + + public int RemoveUnknownAssets() + { + List assets = new List(m_ResourceCollection.GetAssets()); + List removeAssets = assets.FindAll(asset => GetSourceAsset(asset.Guid) == null); + foreach (Asset asset in removeAssets) + { + m_ResourceCollection.UnassignAsset(asset.Guid); + } + + return removeAssets.Count; + } + + public SourceAsset[] GetSourceAssets() + { + int count = 0; + SourceAsset[] sourceAssets = new SourceAsset[m_SourceAssets.Count]; + foreach (KeyValuePair sourceAsset in m_SourceAssets) + { + sourceAssets[count++] = sourceAsset.Value; + } + + return sourceAssets; + } + + public SourceAsset GetSourceAsset(string guid) + { + if (string.IsNullOrEmpty(guid)) + { + return null; + } + + SourceAsset sourceAsset = null; + if (m_SourceAssets.TryGetValue(guid, out sourceAsset)) + { + return sourceAsset; + } + + return null; + } + + public void ScanSourceAssets() + { + m_SourceAssets.Clear(); + m_SourceAssetRoot.Clear(); + + string[] sourceAssetSearchPaths = m_SourceAssetSearchPaths.ToArray(); + HashSet tempGuids = new HashSet(); + tempGuids.UnionWith(AssetDatabase.FindAssets(SourceAssetUnionTypeFilter, sourceAssetSearchPaths)); + tempGuids.UnionWith(AssetDatabase.FindAssets(SourceAssetUnionLabelFilter, sourceAssetSearchPaths)); + tempGuids.ExceptWith(AssetDatabase.FindAssets(SourceAssetExceptTypeFilter, sourceAssetSearchPaths)); + tempGuids.ExceptWith(AssetDatabase.FindAssets(SourceAssetExceptLabelFilter, sourceAssetSearchPaths)); + + string[] guids = new List(tempGuids).ToArray(); + foreach (string guid in guids) + { + string fullPath = AssetDatabase.GUIDToAssetPath(guid); + if (AssetDatabase.IsValidFolder(fullPath)) + { + // Skip folder. + continue; + } + + string assetPath = fullPath.Substring(SourceAssetRootPath.Length + 1); + string[] splitedPath = assetPath.Split('/'); + SourceFolder folder = m_SourceAssetRoot; + for (int i = 0; i < splitedPath.Length - 1; i++) + { + SourceFolder subFolder = folder.GetFolder(splitedPath[i]); + folder = subFolder == null ? folder.AddFolder(splitedPath[i]) : subFolder; + } + + SourceAsset asset = folder.AddAsset(guid, fullPath, splitedPath[splitedPath.Length - 1]); + m_SourceAssets.Add(asset.Guid, asset); + } + } + + private void RefreshSourceAssetSearchPaths() + { + m_SourceAssetSearchPaths.Clear(); + + if (string.IsNullOrEmpty(m_SourceAssetRootPath)) + { + SourceAssetRootPath = DefaultSourceAssetRootPath; + } + + if (m_SourceAssetSearchRelativePaths.Count > 0) + { + foreach (string sourceAssetSearchRelativePath in m_SourceAssetSearchRelativePaths) + { + m_SourceAssetSearchPaths.Add(Utility.Path.GetRegularPath(Path.Combine(m_SourceAssetRootPath, sourceAssetSearchRelativePath))); + } + } + else + { + m_SourceAssetSearchPaths.Add(m_SourceAssetRootPath); + } + } + + private int AssetPathComparer(Asset a, Asset b) + { + SourceAsset sourceAssetA = GetSourceAsset(a.Guid); + SourceAsset sourceAssetB = GetSourceAsset(b.Guid); + + if (sourceAssetA != null && sourceAssetB != null) + { + return sourceAssetA.Path.CompareTo(sourceAssetB.Path); + } + + if (sourceAssetA == null && sourceAssetB == null) + { + return a.Guid.CompareTo(b.Guid); + } + + if (sourceAssetA == null) + { + return -1; + } + + if (sourceAssetB == null) + { + return 1; + } + + return 0; + } + + private int AssetNameComparer(Asset a, Asset b) + { + SourceAsset sourceAssetA = GetSourceAsset(a.Guid); + SourceAsset sourceAssetB = GetSourceAsset(b.Guid); + + if (sourceAssetA != null && sourceAssetB != null) + { + return sourceAssetA.Name.CompareTo(sourceAssetB.Name); + } + + if (sourceAssetA == null && sourceAssetB == null) + { + return a.Guid.CompareTo(b.Guid); + } + + if (sourceAssetA == null) + { + return -1; + } + + if (sourceAssetB == null) + { + return 1; + } + + return 0; + } + + private int AssetGuidComparer(Asset a, Asset b) + { + SourceAsset sourceAssetA = GetSourceAsset(a.Guid); + SourceAsset sourceAssetB = GetSourceAsset(b.Guid); + + if (sourceAssetA != null && sourceAssetB != null || sourceAssetA == null && sourceAssetB == null) + { + return a.Guid.CompareTo(b.Guid); + } + + if (sourceAssetA == null) + { + return -1; + } + + if (sourceAssetB == null) + { + return 1; + } + + return 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorController.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorController.cs.meta new file mode 100644 index 0000000..71601b3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/ResourceEditorController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c8c042eb5e752f49920cfc09aff81c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceAsset.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceAsset.cs new file mode 100644 index 0000000..1684a59 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceAsset.cs @@ -0,0 +1,85 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed class SourceAsset + { + private Texture m_CachedIcon; + + public SourceAsset(string guid, string path, string name, SourceFolder folder) + { + if (folder == null) + { + throw new GameFrameworkException("Source asset folder is invalid."); + } + + Guid = guid; + Path = path; + Name = name; + Folder = folder; + m_CachedIcon = null; + } + + public string Guid + { + get; + private set; + } + + public string Path + { + get; + private set; + } + + public string Name + { + get; + private set; + } + + public SourceFolder Folder + { + get; + private set; + } + + public string FromRootPath + { + get + { + return Folder.Folder == null ? Name : Utility.Text.Format("{0}/{1}", Folder.FromRootPath, Name); + } + } + + public int Depth + { + get + { + return Folder != null ? Folder.Depth + 1 : 0; + } + } + + public Texture Icon + { + get + { + if (m_CachedIcon == null) + { + m_CachedIcon = AssetDatabase.GetCachedIcon(Path); + } + + return m_CachedIcon; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceAsset.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceAsset.cs.meta new file mode 100644 index 0000000..684ff15 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ded5a7d9ccd4b2a409ec840ba3df0b18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceFolder.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceFolder.cs new file mode 100644 index 0000000..69d974b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceFolder.cs @@ -0,0 +1,172 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed class SourceFolder + { + private static Texture s_CachedIcon = null; + + private readonly List m_Folders; + private readonly List m_Assets; + + public SourceFolder(string name, SourceFolder folder) + { + m_Folders = new List(); + m_Assets = new List(); + + Name = name; + Folder = folder; + } + + public string Name + { + get; + private set; + } + + public SourceFolder Folder + { + get; + private set; + } + + public string FromRootPath + { + get + { + return Folder == null ? string.Empty : (Folder.Folder == null ? Name : Utility.Text.Format("{0}/{1}", Folder.FromRootPath, Name)); + } + } + + public int Depth + { + get + { + return Folder != null ? Folder.Depth + 1 : 0; + } + } + + public static Texture Icon + { + get + { + if (s_CachedIcon == null) + { + s_CachedIcon = AssetDatabase.GetCachedIcon("Assets"); + } + + return s_CachedIcon; + } + } + + public void Clear() + { + m_Folders.Clear(); + m_Assets.Clear(); + } + + public SourceFolder[] GetFolders() + { + return m_Folders.ToArray(); + } + + public SourceFolder GetFolder(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Source folder name is invalid."); + } + + foreach (SourceFolder folder in m_Folders) + { + if (folder.Name == name) + { + return folder; + } + } + + return null; + } + + public SourceFolder AddFolder(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Source folder name is invalid."); + } + + SourceFolder folder = GetFolder(name); + if (folder != null) + { + throw new GameFrameworkException("Source folder is already exist."); + } + + folder = new SourceFolder(name, this); + m_Folders.Add(folder); + + return folder; + } + + public SourceAsset[] GetAssets() + { + return m_Assets.ToArray(); + } + + public SourceAsset GetAsset(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Source asset name is invalid."); + } + + foreach (SourceAsset asset in m_Assets) + { + if (asset.Name == name) + { + return asset; + } + } + + return null; + } + + public SourceAsset AddAsset(string guid, string path, string name) + { + if (string.IsNullOrEmpty(guid)) + { + throw new GameFrameworkException("Source asset guid is invalid."); + } + + if (string.IsNullOrEmpty(path)) + { + throw new GameFrameworkException("Source asset path is invalid."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Source asset name is invalid."); + } + + SourceAsset asset = GetAsset(name); + if (asset != null) + { + throw new GameFrameworkException(Utility.Text.Format("Source asset '{0}' is already exist.", name)); + } + + asset = new SourceAsset(guid, path, name, this); + m_Assets.Add(asset); + + return asset; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceFolder.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceFolder.cs.meta new file mode 100644 index 0000000..2732159 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceEditor/SourceFolder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bcb967b558b5d254fb96db1fc5ed808b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder.meta new file mode 100644 index 0000000..c737e64 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3564da2c360cfdb46acffa4b7f42d275 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilder.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilder.cs new file mode 100644 index 0000000..60afb3c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilder.cs @@ -0,0 +1,487 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源包生成器。 + /// + internal sealed class ResourcePackBuilder : EditorWindow + { + private static readonly string[] PlatformForDisplay = new string[] { "Windows", "Windows x64", "macOS", "Linux", "iOS", "Android", "Windows Store", "WebGL" }; + private static readonly int[] LengthLimit = new int[] { 0, 128, 256, 512, 1024, 2048, 4096 }; + private static readonly string[] LengthLimitForDisplay = new string[] { "", "128 MB", "256 MB", "512 MB", "1 GB", "2 GB", "4 GB", "" }; + + private ResourcePackBuilderController m_Controller = null; + private string[] m_VersionNames = null; + private string[] m_VersionNamesForTargetDisplay = null; + private string[] m_VersionNamesForSourceDisplay = null; + private int m_PlatformIndex = 0; + private int m_CompressionHelperTypeNameIndex = 0; + private int m_LengthLimitIndex = 0; + private int m_TargetVersionIndex = 0; + private bool[] m_SourceVersionIndexes = null; + private int m_SourceVersionCount = 0; + + [MenuItem("Game Framework/Resource Tools/Resource Pack Builder", false, 43)] + private static void Open() + { + ResourcePackBuilder window = GetWindow("Resource Pack Builder", true); + window.minSize = new Vector2(800f, 400f); + } + + private void OnEnable() + { + m_Controller = new ResourcePackBuilderController(); + m_Controller.OnBuildResourcePacksStarted += OnBuildResourcePacksStarted; + m_Controller.OnBuildResourcePacksCompleted += OnBuildResourcePacksCompleted; + m_Controller.OnBuildResourcePackSuccess += OnBuildResourcePackSuccess; + m_Controller.OnBuildResourcePackFailure += OnBuildResourcePackFailure; + + m_Controller.Load(); + RefreshVersionNames(); + + m_CompressionHelperTypeNameIndex = 0; + string[] compressionHelperTypeNames = m_Controller.GetCompressionHelperTypeNames(); + for (int i = 0; i < compressionHelperTypeNames.Length; i++) + { + if (m_Controller.CompressionHelperTypeName == compressionHelperTypeNames[i]) + { + m_CompressionHelperTypeNameIndex = i; + break; + } + } + + m_Controller.RefreshCompressionHelper(); + } + + private void Update() + { + } + + private void OnGUI() + { + EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height)); + { + GUILayout.Space(5f); + EditorGUILayout.LabelField("Environment Information", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Product Name", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.ProductName); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Company Name", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.CompanyName); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Game Identifier", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.GameIdentifier); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Game Framework Version", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.GameFrameworkVersion); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Unity Version", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.UnityVersion); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Applicable Game Version", GUILayout.Width(160f)); + EditorGUILayout.LabelField(m_Controller.ApplicableGameVersion); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + GUILayout.Space(5f); + EditorGUILayout.LabelField("Build", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Working Directory", GUILayout.Width(160f)); + string directory = EditorGUILayout.TextField(m_Controller.WorkingDirectory); + if (m_Controller.WorkingDirectory != directory) + { + m_Controller.WorkingDirectory = directory; + RefreshVersionNames(); + } + if (GUILayout.Button("Browse...", GUILayout.Width(80f))) + { + BrowseWorkingDirectory(); + RefreshVersionNames(); + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Platform", GUILayout.Width(160f)); + int platformIndex = EditorGUILayout.Popup(m_PlatformIndex, PlatformForDisplay); + if (m_PlatformIndex != platformIndex) + { + m_PlatformIndex = platformIndex; + m_Controller.Platform = (Platform)(1 << platformIndex); + RefreshVersionNames(); + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Compression Helper", GUILayout.Width(160f)); + string[] names = m_Controller.GetCompressionHelperTypeNames(); + int selectedIndex = EditorGUILayout.Popup(m_CompressionHelperTypeNameIndex, names); + if (selectedIndex != m_CompressionHelperTypeNameIndex) + { + m_CompressionHelperTypeNameIndex = selectedIndex; + m_Controller.CompressionHelperTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex]; + if (m_Controller.RefreshCompressionHelper()) + { + Debug.Log("Set compression helper success."); + } + else + { + Debug.LogWarning("Set compression helper failure."); + } + } + } + EditorGUILayout.EndHorizontal(); + if (m_Controller.Platform == Platform.Undefined || string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName) || !m_Controller.IsValidWorkingDirectory) + { + string message = string.Empty; + if (!m_Controller.IsValidWorkingDirectory) + { + if (!string.IsNullOrEmpty(message)) + { + message += Environment.NewLine; + } + + message += "Working directory is invalid."; + } + + if (m_Controller.Platform == Platform.Undefined) + { + if (!string.IsNullOrEmpty(message)) + { + message += Environment.NewLine; + } + + message += "Platform is invalid."; + } + + if (string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName)) + { + if (!string.IsNullOrEmpty(message)) + { + message += Environment.NewLine; + } + + message += "Compression helper is invalid."; + } + + EditorGUILayout.HelpBox(message, MessageType.Error); + } + else if (m_VersionNamesForTargetDisplay.Length <= 0) + { + EditorGUILayout.HelpBox("No version was found in the specified working directory and platform.", MessageType.Warning); + } + else + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Source Path", GUILayout.Width(160f)); + GUILayout.Label(m_Controller.SourcePathForDisplay); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Output Path", GUILayout.Width(160f)); + GUILayout.Label(m_Controller.OutputPath); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Backup Diff", GUILayout.Width(160f)); + m_Controller.BackupDiff = EditorGUILayout.Toggle(m_Controller.BackupDiff); + } + EditorGUILayout.EndHorizontal(); + if (m_Controller.BackupDiff) + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Backup Version", GUILayout.Width(160f)); + m_Controller.BackupVersion = EditorGUILayout.Toggle(m_Controller.BackupVersion); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Length Limit", GUILayout.Width(160f)); + EditorGUILayout.BeginVertical(); + { + int lengthLimitIndex = EditorGUILayout.Popup(m_LengthLimitIndex, LengthLimitForDisplay); + if (m_LengthLimitIndex != lengthLimitIndex) + { + m_LengthLimitIndex = lengthLimitIndex; + if (m_LengthLimitIndex < LengthLimit.Length) + { + m_Controller.LengthLimit = LengthLimit[m_LengthLimitIndex]; + } + } + + if (m_LengthLimitIndex >= LengthLimit.Length) + { + EditorGUILayout.BeginHorizontal(); + { + m_Controller.LengthLimit = EditorGUILayout.IntField(m_Controller.LengthLimit); + if (m_Controller.LengthLimit < 0) + { + m_Controller.LengthLimit = 0; + } + + GUILayout.Label(" MB", GUILayout.Width(30f)); + } + EditorGUILayout.EndHorizontal(); + } + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Target Version", GUILayout.Width(160f)); + int value = EditorGUILayout.Popup(m_TargetVersionIndex, m_VersionNamesForTargetDisplay); + if (m_TargetVersionIndex != value) + { + m_TargetVersionIndex = value; + RefreshSourceVersionCount(); + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField("Source Version", GUILayout.Width(160f)); + EditorGUILayout.BeginVertical(); + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.LabelField(m_SourceVersionCount.ToString() + (m_SourceVersionCount > 1 ? " items" : " item") + " selected."); + if (GUILayout.Button("Select All Except ", GUILayout.Width(180f))) + { + m_SourceVersionIndexes[0] = false; + for (int i = 1; i < m_SourceVersionIndexes.Length; i++) + { + m_SourceVersionIndexes[i] = true; + } + + RefreshSourceVersionCount(); + } + if (GUILayout.Button("Select All", GUILayout.Width(100f))) + { + for (int i = 0; i < m_SourceVersionIndexes.Length; i++) + { + m_SourceVersionIndexes[i] = true; + } + + RefreshSourceVersionCount(); + } + if (GUILayout.Button("Select None", GUILayout.Width(100f))) + { + for (int i = 0; i < m_SourceVersionIndexes.Length; i++) + { + m_SourceVersionIndexes[i] = false; + } + + RefreshSourceVersionCount(); + } + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + { + int count = m_VersionNamesForSourceDisplay.Length; + int column = 5; + int row = (count - 1) / column + 1; + for (int i = 0; i < column && i < count; i++) + { + EditorGUILayout.BeginVertical(); + { + for (int j = 0; j < row; j++) + { + int index = j * column + i; + if (index < count) + { + bool isTarget = index - 1 == m_TargetVersionIndex; + EditorGUI.BeginDisabledGroup(isTarget); + { + bool selected = GUILayout.Toggle(m_SourceVersionIndexes[index], isTarget ? m_VersionNamesForSourceDisplay[index] + " [Target]" : m_VersionNamesForSourceDisplay[index], "button"); + if (m_SourceVersionIndexes[index] != selected) + { + m_SourceVersionIndexes[index] = selected; + RefreshSourceVersionCount(); + } + } + EditorGUI.EndDisabledGroup(); + } + } + } + EditorGUILayout.EndVertical(); + } + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndHorizontal(); + } + GUILayout.Space(2f); + } + EditorGUILayout.EndVertical(); + GUILayout.Space(2f); + EditorGUILayout.BeginHorizontal(); + { + EditorGUI.BeginDisabledGroup(m_Controller.Platform == Platform.Undefined || string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName) || !m_Controller.IsValidWorkingDirectory || m_SourceVersionCount <= 0); + { + if (GUILayout.Button("Start Build Resource Packs")) + { + string[] sourceVersions = new string[m_SourceVersionCount]; + int count = 0; + for (int i = 0; i < m_SourceVersionIndexes.Length; i++) + { + if (m_SourceVersionIndexes[i]) + { + sourceVersions[count++] = i > 0 ? m_VersionNames[i - 1] : null; + } + } + + m_Controller.BuildResourcePacks(sourceVersions, m_VersionNames[m_TargetVersionIndex]); + } + } + EditorGUI.EndDisabledGroup(); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + } + + private void BrowseWorkingDirectory() + { + string directory = EditorUtility.OpenFolderPanel("Select Working Directory", m_Controller.WorkingDirectory, string.Empty); + if (!string.IsNullOrEmpty(directory)) + { + m_Controller.WorkingDirectory = directory; + } + } + + private void RefreshVersionNames() + { + m_VersionNames = m_Controller.GetVersionNames(); + m_VersionNamesForTargetDisplay = new string[m_VersionNames.Length]; + m_VersionNamesForSourceDisplay = new string[m_VersionNames.Length + 1]; + m_VersionNamesForSourceDisplay[0] = ""; + for (int i = 0; i < m_VersionNames.Length; i++) + { + string versionNameForDisplay = GetVersionNameForDisplay(m_VersionNames[i]); + m_VersionNamesForTargetDisplay[i] = versionNameForDisplay; + m_VersionNamesForSourceDisplay[i + 1] = versionNameForDisplay; + } + + m_TargetVersionIndex = m_VersionNames.Length - 1; + m_SourceVersionIndexes = new bool[m_VersionNames.Length + 1]; + m_SourceVersionCount = 0; + } + + private void RefreshSourceVersionCount() + { + m_SourceVersionIndexes[m_TargetVersionIndex + 1] = false; + m_SourceVersionCount = 0; + if (m_SourceVersionIndexes == null) + { + return; + } + + for (int i = 0; i < m_SourceVersionIndexes.Length; i++) + { + if (m_SourceVersionIndexes[i]) + { + m_SourceVersionCount++; + } + } + } + + private string GetVersionNameForDisplay(string versionName) + { + if (string.IsNullOrEmpty(versionName)) + { + return ""; + } + + string[] splitedVersionNames = versionName.Split('_'); + if (splitedVersionNames.Length < 2) + { + return null; + } + + string text = splitedVersionNames[0]; + for (int i = 1; i < splitedVersionNames.Length - 1; i++) + { + text += "." + splitedVersionNames[i]; + } + + return Utility.Text.Format("{0} ({1})", text, splitedVersionNames[splitedVersionNames.Length - 1]); + } + + private void OnBuildResourcePacksStarted(int count) + { + Debug.Log(Utility.Text.Format("Build resource packs started, '{0}' items to be built.", count)); + EditorUtility.DisplayProgressBar("Build Resource Packs", Utility.Text.Format("Build resource packs, {0} items to be built.", count), 0f); + } + + private void OnBuildResourcePacksCompleted(int successCount, int count) + { + int failureCount = count - successCount; + string str = Utility.Text.Format("Build resource packs completed, '{0}' items, '{1}' success, '{2}' failure.", count, successCount, failureCount); + if (failureCount > 0) + { + Debug.LogWarning(str); + } + else + { + Debug.Log(str); + } + + EditorUtility.ClearProgressBar(); + } + + private void OnBuildResourcePackSuccess(int index, int count, string sourceVersion, string targetVersion) + { + Debug.Log(Utility.Text.Format("Build resource packs success, source version '{0}', target version '{1}'.", GetVersionNameForDisplay(sourceVersion), GetVersionNameForDisplay(targetVersion))); + EditorUtility.DisplayProgressBar("Build Resource Packs", Utility.Text.Format("Build resource packs, {0}/{1} completed.", index + 1, count), (float)index / count); + } + + private void OnBuildResourcePackFailure(int index, int count, string sourceVersion, string targetVersion) + { + Debug.LogWarning(Utility.Text.Format("Build resource packs failure, source version '{0}', target version '{1}'.", GetVersionNameForDisplay(sourceVersion), GetVersionNameForDisplay(targetVersion))); + EditorUtility.DisplayProgressBar("Build Resource Packs", Utility.Text.Format("Build resource packs, {0}/{1} completed.", index + 1, count), (float)index / count); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilder.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilder.cs.meta new file mode 100644 index 0000000..8cbf15a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e260afdf322bd1f4897314c0d2c777d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilderController.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilderController.cs new file mode 100644 index 0000000..477d73f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilderController.cs @@ -0,0 +1,558 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using UnityEditor; +using UnityEngine; +using UnityGameFramework.Runtime; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed class ResourcePackBuilderController + { + private const string DefaultResourcePackName = "GameFrameworkResourcePack"; + private const string DefaultExtension = "dat"; + private const string NoneOptionName = ""; + private static readonly string[] EmptyStringArray = new string[0]; + private static readonly UpdatableVersionList.Resource[] EmptyResourceArray = new UpdatableVersionList.Resource[0]; + + private readonly string m_ConfigurationPath; + private readonly List m_CompressionHelperTypeNames; + private readonly UpdatableVersionListSerializer m_UpdatableVersionListSerializer; + private readonly ResourcePackVersionListSerializer m_ResourcePackVersionListSerializer; + + public ResourcePackBuilderController() + { + m_ConfigurationPath = Type.GetConfigurationPath() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/ResourceBuilder.xml")); + + m_UpdatableVersionListSerializer = new UpdatableVersionListSerializer(); + m_UpdatableVersionListSerializer.RegisterDeserializeCallback(0, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V0); + m_UpdatableVersionListSerializer.RegisterDeserializeCallback(1, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V1); + m_UpdatableVersionListSerializer.RegisterDeserializeCallback(2, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V2); + + m_ResourcePackVersionListSerializer = new ResourcePackVersionListSerializer(); + m_ResourcePackVersionListSerializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback_V0); + + m_CompressionHelperTypeNames = new List + { + NoneOptionName + }; + + m_CompressionHelperTypeNames.AddRange(Type.GetRuntimeOrEditorTypeNames(typeof(Utility.Compression.ICompressionHelper))); + + Platform = Platform.Windows; + CompressionHelperTypeName = string.Empty; + } + + public string ProductName + { + get + { + return PlayerSettings.productName; + } + } + + public string CompanyName + { + get + { + return PlayerSettings.companyName; + } + } + + public string GameIdentifier + { + get + { +#if UNITY_5_6_OR_NEWER + return PlayerSettings.applicationIdentifier; +#else + return PlayerSettings.bundleIdentifier; +#endif + } + } + + public string GameFrameworkVersion + { + get + { + return GameFramework.Version.GameFrameworkVersion; + } + } + + public string UnityVersion + { + get + { + return Application.unityVersion; + } + } + + public string ApplicableGameVersion + { + get + { + return Application.version; + } + } + + public string WorkingDirectory + { + get; + set; + } + + public Platform Platform + { + get; + set; + } + + public string CompressionHelperTypeName + { + get; + set; + } + + public bool BackupDiff + { + get; + set; + } + + public bool BackupVersion + { + get; + set; + } + + public int LengthLimit + { + get; + set; + } + + public bool IsValidWorkingDirectory + { + get + { + if (string.IsNullOrEmpty(WorkingDirectory)) + { + return false; + } + + if (!Directory.Exists(WorkingDirectory)) + { + return false; + } + + return true; + } + } + + public string SourcePath + { + get + { + if (!IsValidWorkingDirectory) + { + return string.Empty; + } + + return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Full/", WorkingDirectory)).FullName); + } + } + + public string SourcePathForDisplay + { + get + { + if (!IsValidWorkingDirectory) + { + return string.Empty; + } + + return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Full/*/{1}/", WorkingDirectory, Platform)).FullName); + } + } + + public string OutputPath + { + get + { + if (!IsValidWorkingDirectory) + { + return string.Empty; + } + + return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/ResourcePack/{1}/", WorkingDirectory, Platform)).FullName); + } + } + + public event GameFrameworkAction OnBuildResourcePacksStarted = null; + + public event GameFrameworkAction OnBuildResourcePacksCompleted = null; + + public event GameFrameworkAction OnBuildResourcePackSuccess = null; + + public event GameFrameworkAction OnBuildResourcePackFailure = null; + + public bool Load() + { + if (!File.Exists(m_ConfigurationPath)) + { + return false; + } + + try + { + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.Load(m_ConfigurationPath); + XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework"); + XmlNode xmlEditor = xmlRoot.SelectSingleNode("ResourceBuilder"); + XmlNode xmlSettings = xmlEditor.SelectSingleNode("Settings"); + + XmlNodeList xmlNodeList = null; + XmlNode xmlNode = null; + + xmlNodeList = xmlSettings.ChildNodes; + for (int i = 0; i < xmlNodeList.Count; i++) + { + xmlNode = xmlNodeList.Item(i); + switch (xmlNode.Name) + { + case "CompressionHelperTypeName": + CompressionHelperTypeName = xmlNode.InnerText; + break; + + case "OutputDirectory": + WorkingDirectory = xmlNode.InnerText; + break; + } + } + } + catch + { + return false; + } + + return true; + } + + public string[] GetCompressionHelperTypeNames() + { + return m_CompressionHelperTypeNames.ToArray(); + } + + public string[] GetVersionNames() + { + if (Platform == Platform.Undefined || !IsValidWorkingDirectory) + { + return EmptyStringArray; + } + + string platformName = Platform.ToString(); + DirectoryInfo sourceDirectoryInfo = new DirectoryInfo(SourcePath); + if (!sourceDirectoryInfo.Exists) + { + return EmptyStringArray; + } + + List versionNames = new List(); + foreach (DirectoryInfo directoryInfo in sourceDirectoryInfo.GetDirectories()) + { + string[] splitedVersionNames = directoryInfo.Name.Split('_'); + if (splitedVersionNames.Length < 2) + { + continue; + } + + bool invalid = false; + int value = 0; + for (int i = 0; i < splitedVersionNames.Length; i++) + { + if (!int.TryParse(splitedVersionNames[i], out value)) + { + invalid = true; + break; + } + } + + if (invalid) + { + continue; + } + + DirectoryInfo platformDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfo.FullName, platformName)); + if (!platformDirectoryInfo.Exists) + { + continue; + } + + FileInfo[] versionListFiles = platformDirectoryInfo.GetFiles("GameFrameworkVersion.*.dat", SearchOption.TopDirectoryOnly); + if (versionListFiles.Length != 1) + { + continue; + } + + versionNames.Add(directoryInfo.Name); + } + + versionNames.Sort((x, y) => + { + return int.Parse(x.Substring(x.LastIndexOf('_') + 1)).CompareTo(int.Parse(y.Substring(y.LastIndexOf('_') + 1))); + }); + + return versionNames.ToArray(); + } + + public bool RefreshCompressionHelper() + { + bool retVal = false; + if (!string.IsNullOrEmpty(CompressionHelperTypeName) && m_CompressionHelperTypeNames.Contains(CompressionHelperTypeName)) + { + System.Type compressionHelperType = Utility.Assembly.GetType(CompressionHelperTypeName); + if (compressionHelperType != null) + { + Utility.Compression.ICompressionHelper compressionHelper = (Utility.Compression.ICompressionHelper)Activator.CreateInstance(compressionHelperType); + if (compressionHelper != null) + { + Utility.Compression.SetCompressionHelper(compressionHelper); + return true; + } + } + } + else + { + retVal = true; + } + + CompressionHelperTypeName = string.Empty; + Utility.Compression.SetCompressionHelper(null); + return retVal; + } + + public void BuildResourcePacks(string[] sourceVersions, string targetVersion) + { + int count = sourceVersions.Length; + if (OnBuildResourcePacksStarted != null) + { + OnBuildResourcePacksStarted(count); + } + + int successCount = 0; + for (int i = 0; i < count; i++) + { + if (BuildResourcePack(sourceVersions[i], targetVersion)) + { + successCount++; + if (OnBuildResourcePackSuccess != null) + { + OnBuildResourcePackSuccess(i, count, sourceVersions[i], targetVersion); + } + } + else + { + if (OnBuildResourcePackFailure != null) + { + OnBuildResourcePackFailure(i, count, sourceVersions[i], targetVersion); + } + } + } + + if (OnBuildResourcePacksCompleted != null) + { + OnBuildResourcePacksCompleted(successCount, count); + } + } + + public bool BuildResourcePack(string sourceVersion, string targetVersion) + { + try + { + if (!Directory.Exists(OutputPath)) + { + Directory.CreateDirectory(OutputPath); + } + + string defaultBackupDiffPath = Path.Combine(OutputPath, DefaultResourcePackName); + string defaultResourcePackName = Utility.Text.Format("{0}.{1}", defaultBackupDiffPath, DefaultExtension); + if (File.Exists(defaultResourcePackName)) + { + File.Delete(defaultResourcePackName); + } + + if (BackupDiff) + { + if (Directory.Exists(defaultBackupDiffPath)) + { + Directory.Delete(defaultBackupDiffPath, true); + } + + Directory.CreateDirectory(defaultBackupDiffPath); + } + + UpdatableVersionList sourceUpdatableVersionList = default(UpdatableVersionList); + if (sourceVersion != null) + { + DirectoryInfo sourceDirectoryInfo = new DirectoryInfo(Path.Combine(Path.Combine(SourcePath, sourceVersion), Platform.ToString())); + FileInfo[] sourceVersionListFiles = sourceDirectoryInfo.GetFiles("GameFrameworkVersion.*.dat", SearchOption.TopDirectoryOnly); + byte[] sourceVersionListBytes = File.ReadAllBytes(sourceVersionListFiles[0].FullName); + sourceVersionListBytes = Utility.Compression.Decompress(sourceVersionListBytes); + using (Stream stream = new MemoryStream(sourceVersionListBytes)) + { + sourceUpdatableVersionList = m_UpdatableVersionListSerializer.Deserialize(stream); + } + } + + UpdatableVersionList targetUpdatableVersionList = default(UpdatableVersionList); + DirectoryInfo targetDirectoryInfo = new DirectoryInfo(Path.Combine(Path.Combine(SourcePath, targetVersion), Platform.ToString())); + FileInfo[] targetVersionListFiles = targetDirectoryInfo.GetFiles("GameFrameworkVersion.*.dat", SearchOption.TopDirectoryOnly); + byte[] targetVersionListBytes = File.ReadAllBytes(targetVersionListFiles[0].FullName); + targetVersionListBytes = Utility.Compression.Decompress(targetVersionListBytes); + using (Stream stream = new MemoryStream(targetVersionListBytes)) + { + targetUpdatableVersionList = m_UpdatableVersionListSerializer.Deserialize(stream); + } + + List resources = new List(); + UpdatableVersionList.Resource[] sourceResources = sourceUpdatableVersionList.IsValid ? sourceUpdatableVersionList.GetResources() : EmptyResourceArray; + UpdatableVersionList.Resource[] targetResources = targetUpdatableVersionList.GetResources(); + long offset = 0L; + foreach (UpdatableVersionList.Resource targetResource in targetResources) + { + bool ready = false; + foreach (UpdatableVersionList.Resource sourceResource in sourceResources) + { + if (sourceResource.Name != targetResource.Name || sourceResource.Variant != targetResource.Variant || sourceResource.Extension != targetResource.Extension) + { + continue; + } + + if (sourceResource.LoadType == targetResource.LoadType && sourceResource.Length == targetResource.Length && sourceResource.HashCode == targetResource.HashCode) + { + ready = true; + } + + break; + } + + if (!ready) + { + resources.Add(new ResourcePackVersionList.Resource(targetResource.Name, targetResource.Variant, targetResource.Extension, targetResource.LoadType, offset, targetResource.Length, targetResource.HashCode, targetResource.CompressedLength, targetResource.CompressedHashCode)); + offset += targetResource.CompressedLength; + } + } + + ResourcePackVersionList.Resource[] resourceArray = resources.ToArray(); + using (FileStream fileStream = new FileStream(defaultResourcePackName, FileMode.Create, FileAccess.Write)) + { + if (!m_ResourcePackVersionListSerializer.Serialize(fileStream, new ResourcePackVersionList(0, 0L, 0, resourceArray))) + { + return false; + } + } + + int position = 0; + int hashCode = 0; + string targetDirectoryPath = targetDirectoryInfo.FullName; + using (FileStream fileStream = new FileStream(defaultResourcePackName, FileMode.Open, FileAccess.ReadWrite)) + { + position = (int)fileStream.Length; + fileStream.Position = position; + foreach (ResourcePackVersionList.Resource resource in resourceArray) + { + string resourceName = Path.Combine(targetDirectoryPath, GetResourceFullName(resource.Name, resource.Variant, resource.HashCode)); + if (!File.Exists(resourceName)) + { + return false; + } + + byte[] resourceBytes = File.ReadAllBytes(resourceName); + fileStream.Write(resourceBytes, 0, resourceBytes.Length); + if (BackupDiff) + { + string backupDiffName = Path.Combine(defaultBackupDiffPath, GetResourceFullName(resource.Name, resource.Variant, resource.HashCode)); + string directoryName = Path.GetDirectoryName(backupDiffName); + if (!Directory.Exists(directoryName)) + { + Directory.CreateDirectory(directoryName); + } + + File.WriteAllBytes(backupDiffName, resourceBytes); + } + } + + if (fileStream.Position - position != offset) + { + return false; + } + + fileStream.Position = position; + hashCode = Utility.Verifier.GetCrc32(fileStream); + + fileStream.Position = 0L; + if (!m_ResourcePackVersionListSerializer.Serialize(fileStream, new ResourcePackVersionList(position, offset, hashCode, resourceArray))) + { + return false; + } + } + + string backupDiffPath = Path.Combine(OutputPath, Utility.Text.Format("{0}-{1}-{2}", DefaultResourcePackName, sourceVersion ?? GetNoneVersion(targetVersion), targetVersion)); + string resourcePackName = Utility.Text.Format("{0}.{1:x8}.{2}", backupDiffPath, hashCode, DefaultExtension); + if (File.Exists(resourcePackName)) + { + File.Delete(resourcePackName); + } + + File.Move(defaultResourcePackName, resourcePackName); + + if (BackupDiff) + { + if (BackupVersion) + { + File.Copy(targetVersionListFiles[0].FullName, Path.Combine(defaultBackupDiffPath, Path.GetFileName(targetVersionListFiles[0].FullName))); + } + + if (Directory.Exists(backupDiffPath)) + { + Directory.Delete(backupDiffPath, true); + } + + Directory.Move(defaultBackupDiffPath, backupDiffPath); + } + + return true; + } + catch + { + return false; + } + } + + private string GetNoneVersion(string targetVersion) + { + string[] splitedVersionNames = targetVersion.Split('_'); + for (int i = 0; i < splitedVersionNames.Length; i++) + { + splitedVersionNames[i] = "0"; + } + + return string.Join("_", splitedVersionNames); + } + + private string GetResourceFullName(string name, string variant, int hashCode) + { + return !string.IsNullOrEmpty(variant) ? Utility.Text.Format("{0}.{1}.{2:x8}.{3}", name, variant, hashCode, DefaultExtension) : Utility.Text.Format("{0}.{1:x8}.{2}", name, hashCode, DefaultExtension); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilderController.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilderController.cs.meta new file mode 100644 index 0000000..ddf0964 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourcePackBuilder/ResourcePackBuilderController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 886e7d3c19662474caeb030f5b2d9a4e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools.meta new file mode 100644 index 0000000..78f6e43 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3d96add3948f44049bb53f4207cdee15 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncTools.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncTools.cs new file mode 100644 index 0000000..9a0d9bb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncTools.cs @@ -0,0 +1,115 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEditor; +using UnityEngine; + +namespace UnityGameFramework.Editor.ResourceTools +{ + /// + /// 资源同步工具。 + /// + internal sealed class ResourceSyncTools : EditorWindow + { + private const float ButtonHeight = 60f; + private const float ButtonSpace = 5f; + private ResourceSyncToolsController m_Controller = null; + + [MenuItem("Game Framework/Resource Tools/Resource Sync Tools", false, 44)] + private static void Open() + { + ResourceSyncTools window = GetWindow("Resource Sync Tools", true); +#if UNITY_2019_3_OR_NEWER + window.minSize = new Vector2(400, 195f); +#else + window.minSize = new Vector2(400, 205f); +#endif + } + + private void OnEnable() + { + m_Controller = new ResourceSyncToolsController(); + m_Controller.OnLoadingResource += OnLoadingResource; + m_Controller.OnLoadingAsset += OnLoadingAsset; + m_Controller.OnCompleted += OnCompleted; + m_Controller.OnResourceDataChanged += OnResourceDataChanged; + } + + private void OnGUI() + { + EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height)); + { + GUILayout.Space(ButtonSpace); + if (GUILayout.Button("Remove All Asset Bundle Names in Project", GUILayout.Height(ButtonHeight))) + { + if (!m_Controller.RemoveAllAssetBundleNames()) + { + Debug.LogWarning("Remove All Asset Bundle Names in Project failure."); + } + else + { + Debug.Log("Remove All Asset Bundle Names in Project completed."); + } + + AssetDatabase.Refresh(); + } + + GUILayout.Space(ButtonSpace); + if (GUILayout.Button("Sync ResourceCollection.xml to Project", GUILayout.Height(ButtonHeight))) + { + if (!m_Controller.SyncToProject()) + { + Debug.LogWarning("Sync ResourceCollection.xml to Project failure."); + } + else + { + Debug.Log("Sync ResourceCollection.xml to Project completed."); + } + + AssetDatabase.Refresh(); + } + + GUILayout.Space(ButtonSpace); + if (GUILayout.Button("Sync ResourceCollection.xml from Project", GUILayout.Height(ButtonHeight))) + { + if (!m_Controller.SyncFromProject()) + { + Debug.LogWarning("Sync Project to ResourceCollection.xml failure."); + } + else + { + Debug.Log("Sync Project to ResourceCollection.xml completed."); + } + + AssetDatabase.Refresh(); + } + } + EditorGUILayout.EndVertical(); + } + + private void OnLoadingResource(int index, int count) + { + EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index, count), (float)index / count); + } + + private void OnLoadingAsset(int index, int count) + { + EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index, count), (float)index / count); + } + + private void OnCompleted() + { + EditorUtility.ClearProgressBar(); + } + + private void OnResourceDataChanged(int index, int count, string assetName) + { + EditorUtility.DisplayProgressBar("Processing Assets", Utility.Text.Format("({0}/{1}) {2}", index, count, assetName), (float)index / count); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncTools.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncTools.cs.meta new file mode 100644 index 0000000..72a8983 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncTools.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d691ed24af244ff41a3012f66ca3ef80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncToolsController.cs b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncToolsController.cs new file mode 100644 index 0000000..12c5287 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncToolsController.cs @@ -0,0 +1,229 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; + +namespace UnityGameFramework.Editor.ResourceTools +{ + public sealed class ResourceSyncToolsController + { + public ResourceSyncToolsController() + { + } + + public event GameFrameworkAction OnLoadingResource = null; + + public event GameFrameworkAction OnLoadingAsset = null; + + public event GameFrameworkAction OnCompleted = null; + + public event GameFrameworkAction OnResourceDataChanged = null; + + public string[] GetAllAssetBundleNames() + { + return AssetDatabase.GetAllAssetBundleNames(); + } + + public string[] GetUsedAssetBundleNames() + { + HashSet hashSet = new HashSet(GetAllAssetBundleNames()); + hashSet.ExceptWith(GetUnusedAssetBundleNames()); + return hashSet.ToArray(); + } + + public string[] GetUnusedAssetBundleNames() + { + return AssetDatabase.GetUnusedAssetBundleNames(); + } + + public string[] GetAssetPathsFromAssetBundle(string assetBundleName) + { + return AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName); + } + + public string[] GetAssetPathsFromAssetBundleAndAssetName(string assetBundleName, string assetName) + { + return AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(assetBundleName, assetName); + } + + public bool RemoveAssetBundleName(string assetBundleName, bool forceRemove) + { + return AssetDatabase.RemoveAssetBundleName(assetBundleName, forceRemove); + } + + public void RemoveUnusedAssetBundleNames() + { + AssetDatabase.RemoveUnusedAssetBundleNames(); + } + + public bool RemoveAllAssetBundleNames() + { + HashSet allAssetNames = new HashSet(); + string[] assetBundleNames = GetUsedAssetBundleNames(); + foreach (string assetBundleName in assetBundleNames) + { + string[] assetNames = GetAssetPathsFromAssetBundle(assetBundleName); + foreach (string assetName in assetNames) + { + allAssetNames.Add(assetName); + } + } + + int assetIndex = 0; + int assetCount = allAssetNames.Count; + foreach (string assetName in allAssetNames) + { + AssetImporter assetImporter = AssetImporter.GetAtPath(assetName); + if (assetImporter == null) + { + if (OnCompleted != null) + { + OnCompleted(); + } + + return false; + } + + assetImporter.assetBundleVariant = null; + assetImporter.assetBundleName = null; + assetImporter.SaveAndReimport(); + + if (OnResourceDataChanged != null) + { + OnResourceDataChanged(++assetIndex, assetCount, assetName); + } + } + + RemoveUnusedAssetBundleNames(); + + if (OnCompleted != null) + { + OnCompleted(); + } + + return true; + } + + public bool SyncToProject() + { + ResourceCollection resourceCollection = new ResourceCollection(); + + resourceCollection.OnLoadingResource += delegate (int index, int count) + { + if (OnLoadingResource != null) + { + OnLoadingResource(index, count); + } + }; + + resourceCollection.OnLoadingAsset += delegate (int index, int count) + { + if (OnLoadingAsset != null) + { + OnLoadingAsset(index, count); + } + }; + + resourceCollection.OnLoadCompleted += delegate () + { + if (OnCompleted != null) + { + OnCompleted(); + } + }; + + if (!resourceCollection.Load()) + { + return false; + } + + int assetIndex = 0; + int assetCount = resourceCollection.AssetCount; + Resource[] resources = resourceCollection.GetResources(); + foreach (Resource resource in resources) + { + if (resource.IsLoadFromBinary) + { + continue; + } + + Asset[] assets = resource.GetAssets(); + foreach (Asset asset in assets) + { + AssetImporter assetImporter = AssetImporter.GetAtPath(asset.Name); + if (assetImporter == null) + { + if (OnCompleted != null) + { + OnCompleted(); + } + + return false; + } + + assetImporter.assetBundleName = resource.Name; + assetImporter.assetBundleVariant = resource.Variant; + assetImporter.SaveAndReimport(); + + if (OnResourceDataChanged != null) + { + OnResourceDataChanged(++assetIndex, assetCount, asset.Name); + } + } + } + + if (OnCompleted != null) + { + OnCompleted(); + } + + return true; + } + + public bool SyncFromProject() + { + ResourceCollection resourceCollection = new ResourceCollection(); + string[] assetBundleNames = GetUsedAssetBundleNames(); + foreach (string assetBundleName in assetBundleNames) + { + string name = assetBundleName; + string variant = null; + int dotPosition = assetBundleName.LastIndexOf('.'); + if (dotPosition > 0 && dotPosition < assetBundleName.Length - 1) + { + name = assetBundleName.Substring(0, dotPosition); + variant = assetBundleName.Substring(dotPosition + 1); + } + + if (!resourceCollection.AddResource(name, variant, null, LoadType.LoadFromFile, false)) + { + return false; + } + + string[] assetNames = GetAssetPathsFromAssetBundle(assetBundleName); + foreach (string assetName in assetNames) + { + string guid = AssetDatabase.AssetPathToGUID(assetName); + if (string.IsNullOrEmpty(guid)) + { + return false; + } + + if (!resourceCollection.AssignAsset(guid, name, variant)) + { + return false; + } + } + } + + return resourceCollection.Save(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncToolsController.cs.meta b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncToolsController.cs.meta new file mode 100644 index 0000000..b3a7631 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/ResourceSyncTools/ResourceSyncToolsController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 210d0e0a522f6c540b17cf9fe64b71e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Editor/UnityGameFrameworkEditor.asmdef b/Packages/com.bywaystudios.gameframework/Editor/UnityGameFrameworkEditor.asmdef new file mode 100644 index 0000000..65e1a94 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/UnityGameFrameworkEditor.asmdef @@ -0,0 +1,19 @@ +{ + "name": "UnityGameFrameworkEditor", + "rootNamespace": "", + "references": [ + "GameFramework", + "UnityGameFramework" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.gameframework/Editor/UnityGameFrameworkEditor.asmdef.meta b/Packages/com.bywaystudios.gameframework/Editor/UnityGameFrameworkEditor.asmdef.meta new file mode 100644 index 0000000..dc6787a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Editor/UnityGameFrameworkEditor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 93fd999929b9ace4e860eb6f24522d48 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime.meta b/Packages/com.bywaystudios.gameframework/Runtime.meta new file mode 100644 index 0000000..ef60277 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: da99d8863a05d124393540b57b7d3889 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework.meta new file mode 100644 index 0000000..778ae56 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 69984e46e21e29440971553e088f73fd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base.meta new file mode 100644 index 0000000..ba6c159 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b4e69d803452d434f9861cc3b4af3253 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider.meta new file mode 100644 index 0000000..b8b7b02 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4448b6e07f805d241aaae133fb0c3715 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProvider.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProvider.cs new file mode 100644 index 0000000..a4e82c5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProvider.cs @@ -0,0 +1,500 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; + +namespace GameFramework +{ + /// + /// 数据提供者。 + /// + /// 数据提供者的持有者的类型。 + internal sealed class DataProvider : IDataProvider + { + private const int BlockSize = 1024 * 4; + private static byte[] s_CachedBytes = null; + + private readonly T m_Owner; + private readonly LoadAssetCallbacks m_LoadAssetCallbacks; + private readonly LoadBinaryCallbacks m_LoadBinaryCallbacks; + private IResourceManager m_ResourceManager; + private IDataProviderHelper m_DataProviderHelper; + private EventHandler m_ReadDataSuccessEventHandler; + private EventHandler m_ReadDataFailureEventHandler; + private EventHandler m_ReadDataUpdateEventHandler; + private EventHandler m_ReadDataDependencyAssetEventHandler; + + /// + /// 初始化数据提供者的新实例。 + /// + /// 数据提供者的持有者。 + public DataProvider(T owner) + { + m_Owner = owner; + m_LoadAssetCallbacks = new LoadAssetCallbacks(LoadAssetSuccessCallback, LoadAssetOrBinaryFailureCallback, LoadAssetUpdateCallback, LoadAssetDependencyAssetCallback); + m_LoadBinaryCallbacks = new LoadBinaryCallbacks(LoadBinarySuccessCallback, LoadAssetOrBinaryFailureCallback); + m_ResourceManager = null; + m_DataProviderHelper = null; + m_ReadDataSuccessEventHandler = null; + m_ReadDataFailureEventHandler = null; + m_ReadDataUpdateEventHandler = null; + m_ReadDataDependencyAssetEventHandler = null; + } + + /// + /// 获取缓冲二进制流的大小。 + /// + public static int CachedBytesSize + { + get + { + return s_CachedBytes != null ? s_CachedBytes.Length : 0; + } + } + + /// + /// 读取数据成功事件。 + /// + public event EventHandler ReadDataSuccess + { + add + { + m_ReadDataSuccessEventHandler += value; + } + remove + { + m_ReadDataSuccessEventHandler -= value; + } + } + + /// + /// 读取数据失败事件。 + /// + public event EventHandler ReadDataFailure + { + add + { + m_ReadDataFailureEventHandler += value; + } + remove + { + m_ReadDataFailureEventHandler -= value; + } + } + + /// + /// 读取数据更新事件。 + /// + public event EventHandler ReadDataUpdate + { + add + { + m_ReadDataUpdateEventHandler += value; + } + remove + { + m_ReadDataUpdateEventHandler -= value; + } + } + + /// + /// 读取数据时加载依赖资源事件。 + /// + public event EventHandler ReadDataDependencyAsset + { + add + { + m_ReadDataDependencyAssetEventHandler += value; + } + remove + { + m_ReadDataDependencyAssetEventHandler -= value; + } + } + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + public static void EnsureCachedBytesSize(int ensureSize) + { + if (ensureSize < 0) + { + throw new GameFrameworkException("Ensure size is invalid."); + } + + if (s_CachedBytes == null || s_CachedBytes.Length < ensureSize) + { + FreeCachedBytes(); + int size = (ensureSize - 1 + BlockSize) / BlockSize * BlockSize; + s_CachedBytes = new byte[size]; + } + } + + /// + /// 释放缓存的二进制流。 + /// + public static void FreeCachedBytes() + { + s_CachedBytes = null; + } + + /// + /// 读取数据。 + /// + /// 内容资源名称。 + public void ReadData(string dataAssetName) + { + ReadData(dataAssetName, Constant.DefaultPriority, null); + } + + /// + /// 读取数据。 + /// + /// 内容资源名称。 + /// 加载数据资源的优先级。 + public void ReadData(string dataAssetName, int priority) + { + ReadData(dataAssetName, priority, null); + } + + /// + /// 读取数据。 + /// + /// 内容资源名称。 + /// 用户自定义数据。 + public void ReadData(string dataAssetName, object userData) + { + ReadData(dataAssetName, Constant.DefaultPriority, userData); + } + + /// + /// 读取数据。 + /// + /// 内容资源名称。 + /// 加载数据资源的优先级。 + /// 用户自定义数据。 + public void ReadData(string dataAssetName, int priority, object userData) + { + if (m_ResourceManager == null) + { + throw new GameFrameworkException("You must set resource manager first."); + } + + if (m_DataProviderHelper == null) + { + throw new GameFrameworkException("You must set data provider helper first."); + } + + HasAssetResult result = m_ResourceManager.HasAsset(dataAssetName); + switch (result) + { + case HasAssetResult.AssetOnDisk: + case HasAssetResult.AssetOnFileSystem: + m_ResourceManager.LoadAsset(dataAssetName, priority, m_LoadAssetCallbacks, userData); + break; + + case HasAssetResult.BinaryOnDisk: + m_ResourceManager.LoadBinary(dataAssetName, m_LoadBinaryCallbacks, userData); + break; + + case HasAssetResult.BinaryOnFileSystem: + int dataLength = m_ResourceManager.GetBinaryLength(dataAssetName); + EnsureCachedBytesSize(dataLength); + if (dataLength != m_ResourceManager.LoadBinaryFromFileSystem(dataAssetName, s_CachedBytes)) + { + throw new GameFrameworkException(Utility.Text.Format("Load binary '{0}' from file system with internal error.", dataAssetName)); + } + + try + { + if (!m_DataProviderHelper.ReadData(m_Owner, dataAssetName, s_CachedBytes, 0, dataLength, userData)) + { + throw new GameFrameworkException(Utility.Text.Format("Load data failure in data provider helper, data asset name '{0}'.", dataAssetName)); + } + + if (m_ReadDataSuccessEventHandler != null) + { + ReadDataSuccessEventArgs loadDataSuccessEventArgs = ReadDataSuccessEventArgs.Create(dataAssetName, 0f, userData); + m_ReadDataSuccessEventHandler(this, loadDataSuccessEventArgs); + ReferencePool.Release(loadDataSuccessEventArgs); + } + } + catch (Exception exception) + { + if (m_ReadDataFailureEventHandler != null) + { + ReadDataFailureEventArgs loadDataFailureEventArgs = ReadDataFailureEventArgs.Create(dataAssetName, exception.ToString(), userData); + m_ReadDataFailureEventHandler(this, loadDataFailureEventArgs); + ReferencePool.Release(loadDataFailureEventArgs); + return; + } + + throw; + } + + break; + + default: + throw new GameFrameworkException(Utility.Text.Format("Data asset '{0}' is '{1}'.", dataAssetName, result)); + } + } + + /// + /// 解析内容。 + /// + /// 要解析的内容字符串。 + /// 是否解析内容成功。 + public bool ParseData(string dataString) + { + return ParseData(dataString, null); + } + + /// + /// 解析内容。 + /// + /// 要解析的内容字符串。 + /// 用户自定义数据。 + /// 是否解析内容成功。 + public bool ParseData(string dataString, object userData) + { + if (m_DataProviderHelper == null) + { + throw new GameFrameworkException("You must set data helper first."); + } + + if (dataString == null) + { + throw new GameFrameworkException("Data string is invalid."); + } + + try + { + return m_DataProviderHelper.ParseData(m_Owner, dataString, userData); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Can not parse data string with exception '{0}'.", exception), exception); + } + } + + /// + /// 解析内容。 + /// + /// 要解析的内容二进制流。 + /// 是否解析内容成功。 + public bool ParseData(byte[] dataBytes) + { + if (dataBytes == null) + { + throw new GameFrameworkException("Data bytes is invalid."); + } + + return ParseData(dataBytes, 0, dataBytes.Length, null); + } + + /// + /// 解析内容。 + /// + /// 要解析的内容二进制流。 + /// 用户自定义数据。 + /// 是否解析内容成功。 + public bool ParseData(byte[] dataBytes, object userData) + { + if (dataBytes == null) + { + throw new GameFrameworkException("Data bytes is invalid."); + } + + return ParseData(dataBytes, 0, dataBytes.Length, userData); + } + + /// + /// 解析内容。 + /// + /// 要解析的内容二进制流。 + /// 内容二进制流的起始位置。 + /// 内容二进制流的长度。 + /// 是否解析内容成功。 + public bool ParseData(byte[] dataBytes, int startIndex, int length) + { + return ParseData(dataBytes, startIndex, length, null); + } + + /// + /// 解析内容。 + /// + /// 要解析的内容二进制流。 + /// 内容二进制流的起始位置。 + /// 内容二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析内容成功。 + public bool ParseData(byte[] dataBytes, int startIndex, int length, object userData) + { + if (m_DataProviderHelper == null) + { + throw new GameFrameworkException("You must set data helper first."); + } + + if (dataBytes == null) + { + throw new GameFrameworkException("Data bytes is invalid."); + } + + if (startIndex < 0 || length < 0 || startIndex + length > dataBytes.Length) + { + throw new GameFrameworkException("Start index or length is invalid."); + } + + try + { + return m_DataProviderHelper.ParseData(m_Owner, dataBytes, startIndex, length, userData); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Can not parse data bytes with exception '{0}'.", exception), exception); + } + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + internal void SetResourceManager(IResourceManager resourceManager) + { + if (resourceManager == null) + { + throw new GameFrameworkException("Resource manager is invalid."); + } + + m_ResourceManager = resourceManager; + } + + /// + /// 设置数据提供者辅助器。 + /// + /// 数据提供者辅助器。 + internal void SetDataProviderHelper(IDataProviderHelper dataProviderHelper) + { + if (dataProviderHelper == null) + { + throw new GameFrameworkException("Data provider helper is invalid."); + } + + m_DataProviderHelper = dataProviderHelper; + } + + private void LoadAssetSuccessCallback(string dataAssetName, object dataAsset, float duration, object userData) + { + try + { + if (!m_DataProviderHelper.ReadData(m_Owner, dataAssetName, dataAsset, userData)) + { + throw new GameFrameworkException(Utility.Text.Format("Load data failure in data provider helper, data asset name '{0}'.", dataAssetName)); + } + + if (m_ReadDataSuccessEventHandler != null) + { + ReadDataSuccessEventArgs loadDataSuccessEventArgs = ReadDataSuccessEventArgs.Create(dataAssetName, duration, userData); + m_ReadDataSuccessEventHandler(this, loadDataSuccessEventArgs); + ReferencePool.Release(loadDataSuccessEventArgs); + } + } + catch (Exception exception) + { + if (m_ReadDataFailureEventHandler != null) + { + ReadDataFailureEventArgs loadDataFailureEventArgs = ReadDataFailureEventArgs.Create(dataAssetName, exception.ToString(), userData); + m_ReadDataFailureEventHandler(this, loadDataFailureEventArgs); + ReferencePool.Release(loadDataFailureEventArgs); + return; + } + + throw; + } + finally + { + m_DataProviderHelper.ReleaseDataAsset(m_Owner, dataAsset); + } + } + + private void LoadAssetOrBinaryFailureCallback(string dataAssetName, LoadResourceStatus status, string errorMessage, object userData) + { + string appendErrorMessage = Utility.Text.Format("Load data failure, data asset name '{0}', status '{1}', error message '{2}'.", dataAssetName, status, errorMessage); + if (m_ReadDataFailureEventHandler != null) + { + ReadDataFailureEventArgs loadDataFailureEventArgs = ReadDataFailureEventArgs.Create(dataAssetName, appendErrorMessage, userData); + m_ReadDataFailureEventHandler(this, loadDataFailureEventArgs); + ReferencePool.Release(loadDataFailureEventArgs); + return; + } + + throw new GameFrameworkException(appendErrorMessage); + } + + private void LoadAssetUpdateCallback(string dataAssetName, float progress, object userData) + { + if (m_ReadDataUpdateEventHandler != null) + { + ReadDataUpdateEventArgs loadDataUpdateEventArgs = ReadDataUpdateEventArgs.Create(dataAssetName, progress, userData); + m_ReadDataUpdateEventHandler(this, loadDataUpdateEventArgs); + ReferencePool.Release(loadDataUpdateEventArgs); + } + } + + private void LoadAssetDependencyAssetCallback(string dataAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + if (m_ReadDataDependencyAssetEventHandler != null) + { + ReadDataDependencyAssetEventArgs loadDataDependencyAssetEventArgs = ReadDataDependencyAssetEventArgs.Create(dataAssetName, dependencyAssetName, loadedCount, totalCount, userData); + m_ReadDataDependencyAssetEventHandler(this, loadDataDependencyAssetEventArgs); + ReferencePool.Release(loadDataDependencyAssetEventArgs); + } + } + + private void LoadBinarySuccessCallback(string dataAssetName, byte[] dataBytes, float duration, object userData) + { + try + { + if (!m_DataProviderHelper.ReadData(m_Owner, dataAssetName, dataBytes, 0, dataBytes.Length, userData)) + { + throw new GameFrameworkException(Utility.Text.Format("Load data failure in data provider helper, data asset name '{0}'.", dataAssetName)); + } + + if (m_ReadDataSuccessEventHandler != null) + { + ReadDataSuccessEventArgs loadDataSuccessEventArgs = ReadDataSuccessEventArgs.Create(dataAssetName, duration, userData); + m_ReadDataSuccessEventHandler(this, loadDataSuccessEventArgs); + ReferencePool.Release(loadDataSuccessEventArgs); + } + } + catch (Exception exception) + { + if (m_ReadDataFailureEventHandler != null) + { + ReadDataFailureEventArgs loadDataFailureEventArgs = ReadDataFailureEventArgs.Create(dataAssetName, exception.ToString(), userData); + m_ReadDataFailureEventHandler(this, loadDataFailureEventArgs); + ReferencePool.Release(loadDataFailureEventArgs); + return; + } + + throw; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProvider.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProvider.cs.meta new file mode 100644 index 0000000..e7b4104 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 100ad432d7461fc479f175bf8d56023a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProviderCreator.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProviderCreator.cs new file mode 100644 index 0000000..269f52d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProviderCreator.cs @@ -0,0 +1,77 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; + +namespace GameFramework +{ + /// + /// 数据提供者创建器。 + /// + public static class DataProviderCreator + { + /// + /// 获取缓冲二进制流的大小。 + /// + /// 数据提供者的持有者的类型。 + /// 缓冲二进制流的大小。 + public static int GetCachedBytesSize() + { + return DataProvider.CachedBytesSize; + } + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 数据提供者的持有者的类型。 + /// 要确保二进制流缓存分配内存的大小。 + public static void EnsureCachedBytesSize(int ensureSize) + { + DataProvider.EnsureCachedBytesSize(ensureSize); + } + + /// + /// 释放缓存的二进制流。 + /// + /// 数据提供者的持有者的类型。 + public static void FreeCachedBytes() + { + DataProvider.FreeCachedBytes(); + } + + /// + /// 创建数据提供者。 + /// + /// 数据提供者的持有者的类型。 + /// 数据提供者的持有者。 + /// 资源管理器。 + /// 数据提供者辅助器。 + /// 创建的数据提供者。 + public static IDataProvider Create(T owner, IResourceManager resourceManager, IDataProviderHelper dataProviderHelper) + { + if (owner == null) + { + throw new GameFrameworkException("Owner is invalid."); + } + + if (resourceManager == null) + { + throw new GameFrameworkException("Resource manager is invalid."); + } + + if (dataProviderHelper == null) + { + throw new GameFrameworkException("Data provider helper is invalid."); + } + + DataProvider dataProvider = new DataProvider(owner); + dataProvider.SetResourceManager(resourceManager); + dataProvider.SetDataProviderHelper(dataProviderHelper); + return dataProvider; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProviderCreator.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProviderCreator.cs.meta new file mode 100644 index 0000000..c194bab --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/DataProviderCreator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86d79fd2539ca384f99a0384ee89c072 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProvider.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProvider.cs new file mode 100644 index 0000000..0560bc4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProvider.cs @@ -0,0 +1,115 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + /// + /// 数据提供者接口。 + /// + /// 数据提供者的持有者的类型。 + public interface IDataProvider + { + /// + /// 读取数据成功事件。 + /// + event EventHandler ReadDataSuccess; + + /// + /// 读取数据失败事件。 + /// + event EventHandler ReadDataFailure; + + /// + /// 读取数据更新事件。 + /// + event EventHandler ReadDataUpdate; + + /// + /// 读取数据时加载依赖资源事件。 + /// + event EventHandler ReadDataDependencyAsset; + + /// + /// 读取数据。 + /// + /// 内容资源名称。 + void ReadData(string dataAssetName); + + /// + /// 读取数据。 + /// + /// 内容资源名称。 + /// 加载数据资源的优先级。 + void ReadData(string dataAssetName, int priority); + + /// + /// 读取数据。 + /// + /// 内容资源名称。 + /// 用户自定义数据。 + void ReadData(string dataAssetName, object userData); + + /// + /// 读取数据。 + /// + /// 内容资源名称。 + /// 加载数据资源的优先级。 + /// 用户自定义数据。 + void ReadData(string dataAssetName, int priority, object userData); + + /// + /// 解析内容。 + /// + /// 要解析的内容字符串。 + /// 是否解析内容成功。 + bool ParseData(string dataString); + + /// + /// 解析内容。 + /// + /// 要解析的内容字符串。 + /// 用户自定义数据。 + /// 是否解析内容成功。 + bool ParseData(string dataString, object userData); + + /// + /// 解析内容。 + /// + /// 要解析的内容二进制流。 + /// 是否解析内容成功。 + bool ParseData(byte[] dataBytes); + + /// + /// 解析内容。 + /// + /// 要解析的内容二进制流。 + /// 用户自定义数据。 + /// 是否解析内容成功。 + bool ParseData(byte[] dataBytes, object userData); + + /// + /// 解析内容。 + /// + /// 要解析的内容二进制流。 + /// 内容二进制流的起始位置。 + /// 内容二进制流的长度。 + /// 是否解析内容成功。 + bool ParseData(byte[] dataBytes, int startIndex, int length); + + /// + /// 解析内容。 + /// + /// 要解析的内容二进制流。 + /// 内容二进制流的起始位置。 + /// 内容二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析内容成功。 + bool ParseData(byte[] dataBytes, int startIndex, int length, object userData); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProvider.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProvider.cs.meta new file mode 100644 index 0000000..a0044c6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d93a81f4f7f5873448dc35e9bb34cd21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProviderHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProviderHelper.cs new file mode 100644 index 0000000..a748aea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProviderHelper.cs @@ -0,0 +1,64 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 数据提供者辅助器接口。 + /// + public interface IDataProviderHelper + { + /// + /// 读取数据。 + /// + /// 数据提供者的持有者。 + /// 内容资源名称。 + /// 内容资源。 + /// 用户自定义数据。 + /// 是否读取数据成功。 + bool ReadData(T dataProviderOwner, string dataAssetName, object dataAsset, object userData); + + /// + /// 读取数据。 + /// + /// 数据提供者的持有者。 + /// 内容资源名称。 + /// 内容二进制流。 + /// 内容二进制流的起始位置。 + /// 内容二进制流的长度。 + /// 用户自定义数据。 + /// 是否读取数据成功。 + bool ReadData(T dataProviderOwner, string dataAssetName, byte[] dataBytes, int startIndex, int length, object userData); + + /// + /// 解析内容。 + /// + /// 数据提供者的持有者。 + /// 要解析的内容字符串。 + /// 用户自定义数据。 + /// 是否解析内容成功。 + bool ParseData(T dataProviderOwner, string dataString, object userData); + + /// + /// 解析内容。 + /// + /// 数据提供者的持有者。 + /// 要解析的内容二进制流。 + /// 内容二进制流的起始位置。 + /// 内容二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析内容成功。 + bool ParseData(T dataProviderOwner, byte[] dataBytes, int startIndex, int length, object userData); + + /// + /// 释放内容资源。 + /// + /// 数据提供者的持有者。 + /// 要释放的内容资源。 + void ReleaseDataAsset(T dataProviderOwner, object dataAsset); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProviderHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProviderHelper.cs.meta new file mode 100644 index 0000000..32270fa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/IDataProviderHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 705044b0129127f479cd2a6b984f9d71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataDependencyAssetEventArgs.cs new file mode 100644 index 0000000..1fd5657 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataDependencyAssetEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 读取数据时加载依赖资源事件。 + /// + public sealed class ReadDataDependencyAssetEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化读取数据时加载依赖资源事件的新实例。 + /// + public ReadDataDependencyAssetEventArgs() + { + DataAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取内容资源名称。 + /// + public string DataAssetName + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建读取数据时加载依赖资源事件。 + /// + /// 内容资源名称。 + /// 被加载的依赖资源名称。 + /// 当前已加载依赖资源数量。 + /// 总共加载依赖资源数量。 + /// 用户自定义数据。 + /// 创建的读取数据时加载依赖资源事件。 + public static ReadDataDependencyAssetEventArgs Create(string dataAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + ReadDataDependencyAssetEventArgs loadDataDependencyAssetEventArgs = ReferencePool.Acquire(); + loadDataDependencyAssetEventArgs.DataAssetName = dataAssetName; + loadDataDependencyAssetEventArgs.DependencyAssetName = dependencyAssetName; + loadDataDependencyAssetEventArgs.LoadedCount = loadedCount; + loadDataDependencyAssetEventArgs.TotalCount = totalCount; + loadDataDependencyAssetEventArgs.UserData = userData; + return loadDataDependencyAssetEventArgs; + } + + /// + /// 清理读取数据时加载依赖资源事件。 + /// + public override void Clear() + { + DataAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..d531093 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30266aa250a6daa4a990dbb9ef3242ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataFailureEventArgs.cs new file mode 100644 index 0000000..d7ee6b2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataFailureEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 读取数据失败事件。 + /// + public sealed class ReadDataFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化读取数据失败事件的新实例。 + /// + public ReadDataFailureEventArgs() + { + DataAssetName = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取内容资源名称。 + /// + public string DataAssetName + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建读取数据失败事件。 + /// + /// 内容资源名称。 + /// 错误信息。 + /// 用户自定义数据。 + /// 创建的读取数据失败事件。 + public static ReadDataFailureEventArgs Create(string dataAssetName, string errorMessage, object userData) + { + ReadDataFailureEventArgs loadDataFailureEventArgs = ReferencePool.Acquire(); + loadDataFailureEventArgs.DataAssetName = dataAssetName; + loadDataFailureEventArgs.ErrorMessage = errorMessage; + loadDataFailureEventArgs.UserData = userData; + return loadDataFailureEventArgs; + } + + /// + /// 清理读取数据失败事件。 + /// + public override void Clear() + { + DataAssetName = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataFailureEventArgs.cs.meta new file mode 100644 index 0000000..8b6b37e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8704035784c1e0b40a4db20b58dbca74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataSuccessEventArgs.cs new file mode 100644 index 0000000..3ca54ef --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataSuccessEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 读取数据成功事件。 + /// + public sealed class ReadDataSuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化读取数据成功事件的新实例。 + /// + public ReadDataSuccessEventArgs() + { + DataAssetName = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取内容资源名称。 + /// + public string DataAssetName + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建读取数据成功事件。 + /// + /// 内容资源名称。 + /// 加载持续时间。 + /// 用户自定义数据。 + /// 创建的读取数据成功事件。 + public static ReadDataSuccessEventArgs Create(string dataAssetName, float duration, object userData) + { + ReadDataSuccessEventArgs loadDataSuccessEventArgs = ReferencePool.Acquire(); + loadDataSuccessEventArgs.DataAssetName = dataAssetName; + loadDataSuccessEventArgs.Duration = duration; + loadDataSuccessEventArgs.UserData = userData; + return loadDataSuccessEventArgs; + } + + /// + /// 清理读取数据成功事件。 + /// + public override void Clear() + { + DataAssetName = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataSuccessEventArgs.cs.meta new file mode 100644 index 0000000..9b4c1b9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d919bf628cea6c4c8d4326a63b9e661 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataUpdateEventArgs.cs new file mode 100644 index 0000000..dc68a18 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataUpdateEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 读取数据更新事件。 + /// + public sealed class ReadDataUpdateEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化读取数据更新事件的新实例。 + /// + public ReadDataUpdateEventArgs() + { + DataAssetName = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取内容资源名称。 + /// + public string DataAssetName + { + get; + private set; + } + + /// + /// 获取读取数据进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建读取数据更新事件。 + /// + /// 内容资源名称。 + /// 读取数据进度。 + /// 用户自定义数据。 + /// 创建的读取数据更新事件。 + public static ReadDataUpdateEventArgs Create(string dataAssetName, float progress, object userData) + { + ReadDataUpdateEventArgs loadDataUpdateEventArgs = ReferencePool.Acquire(); + loadDataUpdateEventArgs.DataAssetName = dataAssetName; + loadDataUpdateEventArgs.Progress = progress; + loadDataUpdateEventArgs.UserData = userData; + return loadDataUpdateEventArgs; + } + + /// + /// 清理读取数据更新事件。 + /// + public override void Clear() + { + DataAssetName = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataUpdateEventArgs.cs.meta new file mode 100644 index 0000000..93adb34 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataProvider/ReadDataUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 609c081e8e6872e4aa1f177d3ae866b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct.meta new file mode 100644 index 0000000..62d5729 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8c64bdecb6c506d4386144e1dd28f923 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct/TypeNamePair.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct/TypeNamePair.cs new file mode 100644 index 0000000..8900242 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct/TypeNamePair.cs @@ -0,0 +1,135 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Runtime.InteropServices; + +namespace GameFramework +{ + /// + /// 类型和名称的组合值。 + /// + [StructLayout(LayoutKind.Auto)] + internal struct TypeNamePair : IEquatable + { + private readonly Type m_Type; + private readonly string m_Name; + + /// + /// 初始化类型和名称的组合值的新实例。 + /// + /// 类型。 + public TypeNamePair(Type type) + : this(type, string.Empty) + { + } + + /// + /// 初始化类型和名称的组合值的新实例。 + /// + /// 类型。 + /// 名称。 + public TypeNamePair(Type type, string name) + { + if (type == null) + { + throw new GameFrameworkException("Type is invalid."); + } + + m_Type = type; + m_Name = name ?? string.Empty; + } + + /// + /// 获取类型。 + /// + public Type Type + { + get + { + return m_Type; + } + } + + /// + /// 获取名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取类型和名称的组合值字符串。 + /// + /// 类型和名称的组合值字符串。 + public override string ToString() + { + if (m_Type == null) + { + throw new GameFrameworkException("Type is invalid."); + } + + string typeName = m_Type.FullName; + return string.IsNullOrEmpty(m_Name) ? typeName : Utility.Text.Format("{0}.{1}", typeName, m_Name); + } + + /// + /// 获取对象的哈希值。 + /// + /// 对象的哈希值。 + public override int GetHashCode() + { + return m_Type.GetHashCode() ^ m_Name.GetHashCode(); + } + + /// + /// 比较对象是否与自身相等。 + /// + /// 要比较的对象。 + /// 被比较的对象是否与自身相等。 + public override bool Equals(object obj) + { + return obj is TypeNamePair && Equals((TypeNamePair)obj); + } + + /// + /// 比较对象是否与自身相等。 + /// + /// 要比较的对象。 + /// 被比较的对象是否与自身相等。 + public bool Equals(TypeNamePair value) + { + return m_Type == value.m_Type && m_Name == value.m_Name; + } + + /// + /// 判断两个对象是否相等。 + /// + /// 值 a。 + /// 值 b。 + /// 两个对象是否相等。 + public static bool operator ==(TypeNamePair a, TypeNamePair b) + { + return a.Equals(b); + } + + /// + /// 判断两个对象是否不相等。 + /// + /// 值 a。 + /// 值 b。 + /// 两个对象是否不相等。 + public static bool operator !=(TypeNamePair a, TypeNamePair b) + { + return !(a == b); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct/TypeNamePair.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct/TypeNamePair.cs.meta new file mode 100644 index 0000000..faae6a8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/DataStruct/TypeNamePair.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a84a487fb5393b44bf3ccfcf59b4e27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool.meta new file mode 100644 index 0000000..bf95a0b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7d83cb404c446b44184c3bb71c70dd10 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/BaseEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/BaseEventArgs.cs new file mode 100644 index 0000000..eb7eec6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/BaseEventArgs.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 事件基类。 + /// + public abstract class BaseEventArgs : GameFrameworkEventArgs + { + /// + /// 获取类型编号。 + /// + public abstract int Id + { + get; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/BaseEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/BaseEventArgs.cs.meta new file mode 100644 index 0000000..8f88d99 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/BaseEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 239b76603858e804791214feecfec459 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.Event.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.Event.cs new file mode 100644 index 0000000..1748012 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.Event.cs @@ -0,0 +1,57 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + internal sealed partial class EventPool where T : BaseEventArgs + { + /// + /// 事件结点。 + /// + private sealed class Event : IReference + { + private object m_Sender; + private T m_EventArgs; + + public Event() + { + m_Sender = null; + m_EventArgs = null; + } + + public object Sender + { + get + { + return m_Sender; + } + } + + public T EventArgs + { + get + { + return m_EventArgs; + } + } + + public static Event Create(object sender, T e) + { + Event eventNode = ReferencePool.Acquire(); + eventNode.m_Sender = sender; + eventNode.m_EventArgs = e; + return eventNode; + } + + public void Clear() + { + m_Sender = null; + m_EventArgs = null; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.Event.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.Event.cs.meta new file mode 100644 index 0000000..f35fa9f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.Event.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 570346b27b0057a409776a0643b70ad7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.cs new file mode 100644 index 0000000..296c73e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.cs @@ -0,0 +1,285 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework +{ + /// + /// 事件池。 + /// + /// 事件类型。 + internal sealed partial class EventPool where T : BaseEventArgs + { + private readonly GameFrameworkMultiDictionary> m_EventHandlers; + private readonly Queue m_Events; + private readonly Dictionary>> m_CachedNodes; + private readonly Dictionary>> m_TempNodes; + private readonly EventPoolMode m_EventPoolMode; + private EventHandler m_DefaultHandler; + + /// + /// 初始化事件池的新实例。 + /// + /// 事件池模式。 + public EventPool(EventPoolMode mode) + { + m_EventHandlers = new GameFrameworkMultiDictionary>(); + m_Events = new Queue(); + m_CachedNodes = new Dictionary>>(); + m_TempNodes = new Dictionary>>(); + m_EventPoolMode = mode; + m_DefaultHandler = null; + } + + /// + /// 获取事件处理函数的数量。 + /// + public int EventHandlerCount + { + get + { + return m_EventHandlers.Count; + } + } + + /// + /// 获取事件数量。 + /// + public int EventCount + { + get + { + return m_Events.Count; + } + } + + /// + /// 事件池轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + lock (m_Events) + { + while (m_Events.Count > 0) + { + Event eventNode = m_Events.Dequeue(); + HandleEvent(eventNode.Sender, eventNode.EventArgs); + ReferencePool.Release(eventNode); + } + } + } + + /// + /// 关闭并清理事件池。 + /// + public void Shutdown() + { + Clear(); + m_EventHandlers.Clear(); + m_CachedNodes.Clear(); + m_TempNodes.Clear(); + m_DefaultHandler = null; + } + + /// + /// 清理事件。 + /// + public void Clear() + { + lock (m_Events) + { + m_Events.Clear(); + } + } + + /// + /// 获取事件处理函数的数量。 + /// + /// 事件类型编号。 + /// 事件处理函数的数量。 + public int Count(int id) + { + GameFrameworkLinkedListRange> range = default(GameFrameworkLinkedListRange>); + if (m_EventHandlers.TryGetValue(id, out range)) + { + return range.Count; + } + + return 0; + } + + /// + /// 检查是否存在事件处理函数。 + /// + /// 事件类型编号。 + /// 要检查的事件处理函数。 + /// 是否存在事件处理函数。 + public bool Check(int id, EventHandler handler) + { + if (handler == null) + { + throw new GameFrameworkException("Event handler is invalid."); + } + + return m_EventHandlers.Contains(id, handler); + } + + /// + /// 订阅事件处理函数。 + /// + /// 事件类型编号。 + /// 要订阅的事件处理函数。 + public void Subscribe(int id, EventHandler handler) + { + if (handler == null) + { + throw new GameFrameworkException("Event handler is invalid."); + } + + if (!m_EventHandlers.Contains(id)) + { + m_EventHandlers.Add(id, handler); + } + else if ((m_EventPoolMode & EventPoolMode.AllowMultiHandler) != EventPoolMode.AllowMultiHandler) + { + throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not allow multi handler.", id)); + } + else if ((m_EventPoolMode & EventPoolMode.AllowDuplicateHandler) != EventPoolMode.AllowDuplicateHandler && Check(id, handler)) + { + throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not allow duplicate handler.", id)); + } + else + { + m_EventHandlers.Add(id, handler); + } + } + + /// + /// 取消订阅事件处理函数。 + /// + /// 事件类型编号。 + /// 要取消订阅的事件处理函数。 + public void Unsubscribe(int id, EventHandler handler) + { + if (handler == null) + { + throw new GameFrameworkException("Event handler is invalid."); + } + + if (m_CachedNodes.Count > 0) + { + foreach (KeyValuePair>> cachedNode in m_CachedNodes) + { + if (cachedNode.Value != null && cachedNode.Value.Value == handler) + { + m_TempNodes.Add(cachedNode.Key, cachedNode.Value.Next); + } + } + + if (m_TempNodes.Count > 0) + { + foreach (KeyValuePair>> cachedNode in m_TempNodes) + { + m_CachedNodes[cachedNode.Key] = cachedNode.Value; + } + + m_TempNodes.Clear(); + } + } + + if (!m_EventHandlers.Remove(id, handler)) + { + throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not exists specified handler.", id)); + } + } + + /// + /// 设置默认事件处理函数。 + /// + /// 要设置的默认事件处理函数。 + public void SetDefaultHandler(EventHandler handler) + { + m_DefaultHandler = handler; + } + + /// + /// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。 + /// + /// 事件源。 + /// 事件参数。 + public void Fire(object sender, T e) + { + if (e == null) + { + throw new GameFrameworkException("Event is invalid."); + } + + Event eventNode = Event.Create(sender, e); + lock (m_Events) + { + m_Events.Enqueue(eventNode); + } + } + + /// + /// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。 + /// + /// 事件源。 + /// 事件参数。 + public void FireNow(object sender, T e) + { + if (e == null) + { + throw new GameFrameworkException("Event is invalid."); + } + + HandleEvent(sender, e); + } + + /// + /// 处理事件结点。 + /// + /// 事件源。 + /// 事件参数。 + private void HandleEvent(object sender, T e) + { + bool noHandlerException = false; + GameFrameworkLinkedListRange> range = default(GameFrameworkLinkedListRange>); + if (m_EventHandlers.TryGetValue(e.Id, out range)) + { + LinkedListNode> current = range.First; + while (current != null && current != range.Terminal) + { + m_CachedNodes[e] = current.Next != range.Terminal ? current.Next : null; + current.Value(sender, e); + current = m_CachedNodes[e]; + } + + m_CachedNodes.Remove(e); + } + else if (m_DefaultHandler != null) + { + m_DefaultHandler(sender, e); + } + else if ((m_EventPoolMode & EventPoolMode.AllowNoHandler) == 0) + { + noHandlerException = true; + } + + ReferencePool.Release(e); + + if (noHandlerException) + { + throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not allow no handler.", e.Id)); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.cs.meta new file mode 100644 index 0000000..c59eb8f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b0e963fa2c93564a95dfb0577edd37e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPoolMode.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPoolMode.cs new file mode 100644 index 0000000..46622b0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPoolMode.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + /// + /// 事件池模式。 + /// + [Flags] + internal enum EventPoolMode : byte + { + /// + /// 默认事件池模式,即必须存在有且只有一个事件处理函数。 + /// + Default = 0, + + /// + /// 允许不存在事件处理函数。 + /// + AllowNoHandler = 1, + + /// + /// 允许存在多个事件处理函数。 + /// + AllowMultiHandler = 2, + + /// + /// 允许存在重复的事件处理函数。 + /// + AllowDuplicateHandler = 4 + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPoolMode.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPoolMode.cs.meta new file mode 100644 index 0000000..2fecdc9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/EventPool/EventPoolMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f64a26418a084d46b260d8a36b28ff9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkAction.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkAction.cs new file mode 100644 index 0000000..18c10ed --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkAction.cs @@ -0,0 +1,366 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 封装一个方法,该方法不具有参数并且不返回值。 + /// + public delegate void GameFrameworkAction(); + + /// + /// 封装一个方法,该方法只有一个参数并且不返回值。 + /// + /// 此委托封装的方法的参数类型。 + /// 此委托封装的方法的参数。 + public delegate void GameFrameworkAction(T obj); + + /// + /// 封装一个方法,该方法具有两个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2); + + /// + /// 封装一个方法,该方法具有三个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3); + + /// + /// 封装一个方法,该方法具有四个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4); + + /// + /// 封装一个方法,该方法具有五个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); + + /// + /// 封装一个方法,该方法具有六个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); + + /// + /// 封装一个方法,该方法具有七个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); + + /// + /// 封装一个方法,该方法具有八个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); + + /// + /// 封装一个方法,该方法具有九个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + + /// + /// 封装一个方法,该方法具有十个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + + /// + /// 封装一个方法,该方法具有十一个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + + /// + /// 封装一个方法,该方法具有十二个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + + /// + /// 封装一个方法,该方法具有十三个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第十三个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的第十三个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + + /// + /// 封装一个方法,该方法具有十四个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第十三个参数的类型。 + /// 此委托封装的方法的第十四个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的第十三个参数。 + /// 此委托封装的方法的第十四个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); + + /// + /// 封装一个方法,该方法具有十五个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第十三个参数的类型。 + /// 此委托封装的方法的第十四个参数的类型。 + /// 此委托封装的方法的第十五个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的第十三个参数。 + /// 此委托封装的方法的第十四个参数。 + /// 此委托封装的方法的第十五个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); + + /// + /// 封装一个方法,该方法具有十六个参数并且不返回值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第十三个参数的类型。 + /// 此委托封装的方法的第十四个参数的类型。 + /// 此委托封装的方法的第十五个参数的类型。 + /// 此委托封装的方法的第十六个参数的类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的第十三个参数。 + /// 此委托封装的方法的第十四个参数。 + /// 此委托封装的方法的第十五个参数。 + /// 此委托封装的方法的第十六个参数。 + public delegate void GameFrameworkAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkAction.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkAction.cs.meta new file mode 100644 index 0000000..e2de8ea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkAction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41ef6f3313a0ee94193935b3398cc707 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEntry.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEntry.cs new file mode 100644 index 0000000..e4ea9c2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEntry.cs @@ -0,0 +1,133 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework +{ + /// + /// 游戏框架入口。 + /// + public static class GameFrameworkEntry + { + private static readonly GameFrameworkLinkedList s_GameFrameworkModules = new GameFrameworkLinkedList(); + + /// + /// 所有游戏框架模块轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public static void Update(float elapseSeconds, float realElapseSeconds) + { + foreach (GameFrameworkModule module in s_GameFrameworkModules) + { + module.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理所有游戏框架模块。 + /// + public static void Shutdown() + { + for (LinkedListNode current = s_GameFrameworkModules.Last; current != null; current = current.Previous) + { + current.Value.Shutdown(); + } + + s_GameFrameworkModules.Clear(); + ReferencePool.ClearAll(); + Utility.Marshal.FreeCachedHGlobal(); + GameFrameworkLog.SetLogHelper(null); + } + + /// + /// 获取游戏框架模块。 + /// + /// 要获取的游戏框架模块类型。 + /// 要获取的游戏框架模块。 + /// 如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。 + public static T GetModule() where T : class + { + Type interfaceType = typeof(T); + if (!interfaceType.IsInterface) + { + throw new GameFrameworkException(Utility.Text.Format("You must get module by interface, but '{0}' is not.", interfaceType.FullName)); + } + + if (!interfaceType.FullName.StartsWith("GameFramework.", StringComparison.Ordinal)) + { + throw new GameFrameworkException(Utility.Text.Format("You must get a Game Framework module, but '{0}' is not.", interfaceType.FullName)); + } + + string moduleName = Utility.Text.Format("{0}.{1}", interfaceType.Namespace, interfaceType.Name.Substring(1)); + Type moduleType = Type.GetType(moduleName); + if (moduleType == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find Game Framework module type '{0}'.", moduleName)); + } + + return GetModule(moduleType) as T; + } + + /// + /// 获取游戏框架模块。 + /// + /// 要获取的游戏框架模块类型。 + /// 要获取的游戏框架模块。 + /// 如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。 + private static GameFrameworkModule GetModule(Type moduleType) + { + foreach (GameFrameworkModule module in s_GameFrameworkModules) + { + if (module.GetType() == moduleType) + { + return module; + } + } + + return CreateModule(moduleType); + } + + /// + /// 创建游戏框架模块。 + /// + /// 要创建的游戏框架模块类型。 + /// 要创建的游戏框架模块。 + private static GameFrameworkModule CreateModule(Type moduleType) + { + GameFrameworkModule module = (GameFrameworkModule)Activator.CreateInstance(moduleType); + if (module == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not create module '{0}'.", moduleType.FullName)); + } + + LinkedListNode current = s_GameFrameworkModules.First; + while (current != null) + { + if (module.Priority > current.Value.Priority) + { + break; + } + + current = current.Next; + } + + if (current != null) + { + s_GameFrameworkModules.AddBefore(current, module); + } + else + { + s_GameFrameworkModules.AddLast(module); + } + + return module; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEntry.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEntry.cs.meta new file mode 100644 index 0000000..83aab0f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82e7e350d8653c14da0eab4537c71db0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEventArgs.cs new file mode 100644 index 0000000..5fe3a74 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEventArgs.cs @@ -0,0 +1,29 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + /// + /// 游戏框架中包含事件数据的类的基类。 + /// + public abstract class GameFrameworkEventArgs : EventArgs, IReference + { + /// + /// 初始化游戏框架中包含事件数据的类的新实例。 + /// + public GameFrameworkEventArgs() + { + } + + /// + /// 清理引用。 + /// + public abstract void Clear(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEventArgs.cs.meta new file mode 100644 index 0000000..3a6281f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b9967f560e536794c8d6fd3f9d1002d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkException.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkException.cs new file mode 100644 index 0000000..3366404 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkException.cs @@ -0,0 +1,56 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Runtime.Serialization; + +namespace GameFramework +{ + /// + /// 游戏框架异常类。 + /// + [Serializable] + public class GameFrameworkException : Exception + { + /// + /// 初始化游戏框架异常类的新实例。 + /// + public GameFrameworkException() + : base() + { + } + + /// + /// 使用指定错误消息初始化游戏框架异常类的新实例。 + /// + /// 描述错误的消息。 + public GameFrameworkException(string message) + : base(message) + { + } + + /// + /// 使用指定错误消息和对作为此异常原因的内部异常的引用来初始化游戏框架异常类的新实例。 + /// + /// 解释异常原因的错误消息。 + /// 导致当前异常的异常。如果 innerException 参数不为空引用,则在处理内部异常的 catch 块中引发当前异常。 + public GameFrameworkException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// 用序列化数据初始化游戏框架异常类的新实例。 + /// + /// 存有有关所引发异常的序列化的对象数据。 + /// 包含有关源或目标的上下文信息。 + protected GameFrameworkException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkException.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkException.cs.meta new file mode 100644 index 0000000..b645107 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cec62ac7ce98a56499e2c171d4a22a7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkFunc.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkFunc.cs new file mode 100644 index 0000000..2f1c0fb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkFunc.cs @@ -0,0 +1,400 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 封装一个方法,该方法不具有参数,但却返回 TResult 参数指定的类型的值。 + /// + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(); + + /// + /// 封装一个方法,该方法具有一个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的参数类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T arg); + + /// + /// 封装一个方法,该方法具有两个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2); + + /// + /// 封装一个方法,该方法具有三个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3); + + /// + /// 封装一个方法,该方法具有四个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4); + + /// + /// 封装一个方法,该方法具有五个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); + + /// + /// 封装一个方法,该方法具有六个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); + + /// + /// 封装一个方法,该方法具有七个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); + + /// + /// 封装一个方法,该方法具有八个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); + + /// + /// 封装一个方法,该方法具有九个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + + /// + /// 封装一个方法,该方法具有十个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + + /// + /// 封装一个方法,该方法具有十一个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + + /// + /// 封装一个方法,该方法具有十二个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + + /// + /// 封装一个方法,该方法具有十三个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第十三个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的第十三个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + + /// + /// 封装一个方法,该方法具有十四个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第十三个参数的类型。 + /// 此委托封装的方法的第十四个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的第十三个参数。 + /// 此委托封装的方法的第十四个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); + + /// + /// 封装一个方法,该方法具有十五个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第十三个参数的类型。 + /// 此委托封装的方法的第十四个参数的类型。 + /// 此委托封装的方法的第十五个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的第十三个参数。 + /// 此委托封装的方法的第十四个参数。 + /// 此委托封装的方法的第十五个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); + + /// + /// 封装一个方法,该方法具有十六个参数,并返回 TResult 参数所指定的类型的值。 + /// + /// 此委托封装的方法的第一个参数的类型。 + /// 此委托封装的方法的第二个参数的类型。 + /// 此委托封装的方法的第三个参数的类型。 + /// 此委托封装的方法的第四个参数的类型。 + /// 此委托封装的方法的第五个参数的类型。 + /// 此委托封装的方法的第六个参数的类型。 + /// 此委托封装的方法的第七个参数的类型。 + /// 此委托封装的方法的第八个参数的类型。 + /// 此委托封装的方法的第九个参数的类型。 + /// 此委托封装的方法的第十个参数的类型。 + /// 此委托封装的方法的第十一个参数的类型。 + /// 此委托封装的方法的第十二个参数的类型。 + /// 此委托封装的方法的第十三个参数的类型。 + /// 此委托封装的方法的第十四个参数的类型。 + /// 此委托封装的方法的第十五个参数的类型。 + /// 此委托封装的方法的第十六个参数的类型。 + /// 此委托封装的方法的返回值类型。 + /// 此委托封装的方法的第一个参数。 + /// 此委托封装的方法的第二个参数。 + /// 此委托封装的方法的第三个参数。 + /// 此委托封装的方法的第四个参数。 + /// 此委托封装的方法的第五个参数。 + /// 此委托封装的方法的第六个参数。 + /// 此委托封装的方法的第七个参数。 + /// 此委托封装的方法的第八个参数。 + /// 此委托封装的方法的第九个参数。 + /// 此委托封装的方法的第十个参数。 + /// 此委托封装的方法的第十一个参数。 + /// 此委托封装的方法的第十二个参数。 + /// 此委托封装的方法的第十三个参数。 + /// 此委托封装的方法的第十四个参数。 + /// 此委托封装的方法的第十五个参数。 + /// 此委托封装的方法的第十六个参数。 + /// 此委托封装的方法的返回值。 + public delegate TResult GameFrameworkFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkFunc.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkFunc.cs.meta new file mode 100644 index 0000000..039d9f8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkFunc.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e2a0d9a1eb3b94540b97949e4e49754d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedList.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedList.cs new file mode 100644 index 0000000..0070534 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedList.cs @@ -0,0 +1,453 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace GameFramework +{ + /// + /// 游戏框架链表类。 + /// + /// 指定链表的元素类型。 + public sealed class GameFrameworkLinkedList : ICollection, IEnumerable, ICollection, IEnumerable + { + private readonly LinkedList m_LinkedList; + private readonly Queue> m_CachedNodes; + + /// + /// 初始化游戏框架链表类的新实例。 + /// + public GameFrameworkLinkedList() + { + m_LinkedList = new LinkedList(); + m_CachedNodes = new Queue>(); + } + + /// + /// 获取链表中实际包含的结点数量。 + /// + public int Count + { + get + { + return m_LinkedList.Count; + } + } + + /// + /// 获取链表结点缓存数量。 + /// + public int CachedNodeCount + { + get + { + return m_CachedNodes.Count; + } + } + + /// + /// 获取链表的第一个结点。 + /// + public LinkedListNode First + { + get + { + return m_LinkedList.First; + } + } + + /// + /// 获取链表的最后一个结点。 + /// + public LinkedListNode Last + { + get + { + return m_LinkedList.Last; + } + } + + /// + /// 获取一个值,该值指示 ICollection`1 是否为只读。 + /// + public bool IsReadOnly + { + get + { + return ((ICollection)m_LinkedList).IsReadOnly; + } + } + + /// + /// 获取可用于同步对 ICollection 的访问的对象。 + /// + public object SyncRoot + { + get + { + return ((ICollection)m_LinkedList).SyncRoot; + } + } + + /// + /// 获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。 + /// + public bool IsSynchronized + { + get + { + return ((ICollection)m_LinkedList).IsSynchronized; + } + } + + /// + /// 在链表中指定的现有结点后添加包含指定值的新结点。 + /// + /// 指定的现有结点。 + /// 指定值。 + /// 包含指定值的新结点。 + public LinkedListNode AddAfter(LinkedListNode node, T value) + { + LinkedListNode newNode = AcquireNode(value); + m_LinkedList.AddAfter(node, newNode); + return newNode; + } + + /// + /// 在链表中指定的现有结点后添加指定的新结点。 + /// + /// 指定的现有结点。 + /// 指定的新结点。 + public void AddAfter(LinkedListNode node, LinkedListNode newNode) + { + m_LinkedList.AddAfter(node, newNode); + } + + /// + /// 在链表中指定的现有结点前添加包含指定值的新结点。 + /// + /// 指定的现有结点。 + /// 指定值。 + /// 包含指定值的新结点。 + public LinkedListNode AddBefore(LinkedListNode node, T value) + { + LinkedListNode newNode = AcquireNode(value); + m_LinkedList.AddBefore(node, newNode); + return newNode; + } + + /// + /// 在链表中指定的现有结点前添加指定的新结点。 + /// + /// 指定的现有结点。 + /// 指定的新结点。 + public void AddBefore(LinkedListNode node, LinkedListNode newNode) + { + m_LinkedList.AddBefore(node, newNode); + } + + /// + /// 在链表的开头处添加包含指定值的新结点。 + /// + /// 指定值。 + /// 包含指定值的新结点。 + public LinkedListNode AddFirst(T value) + { + LinkedListNode node = AcquireNode(value); + m_LinkedList.AddFirst(node); + return node; + } + + /// + /// 在链表的开头处添加指定的新结点。 + /// + /// 指定的新结点。 + public void AddFirst(LinkedListNode node) + { + m_LinkedList.AddFirst(node); + } + + /// + /// 在链表的结尾处添加包含指定值的新结点。 + /// + /// 指定值。 + /// 包含指定值的新结点。 + public LinkedListNode AddLast(T value) + { + LinkedListNode node = AcquireNode(value); + m_LinkedList.AddLast(node); + return node; + } + + /// + /// 在链表的结尾处添加指定的新结点。 + /// + /// 指定的新结点。 + public void AddLast(LinkedListNode node) + { + m_LinkedList.AddLast(node); + } + + /// + /// 从链表中移除所有结点。 + /// + public void Clear() + { + LinkedListNode current = m_LinkedList.First; + while (current != null) + { + ReleaseNode(current); + current = current.Next; + } + + m_LinkedList.Clear(); + } + + /// + /// 清除链表结点缓存。 + /// + public void ClearCachedNodes() + { + m_CachedNodes.Clear(); + } + + /// + /// 确定某值是否在链表中。 + /// + /// 指定值。 + /// 某值是否在链表中。 + public bool Contains(T value) + { + return m_LinkedList.Contains(value); + } + + /// + /// 从目标数组的指定索引处开始将整个链表复制到兼容的一维数组。 + /// + /// 一维数组,它是从链表复制的元素的目标。数组必须具有从零开始的索引。 + /// array 中从零开始的索引,从此处开始复制。 + public void CopyTo(T[] array, int index) + { + m_LinkedList.CopyTo(array, index); + } + + /// + /// 从特定的 ICollection 索引开始,将数组的元素复制到一个数组中。 + /// + /// 一维数组,它是从 ICollection 复制的元素的目标。数组必须具有从零开始的索引。 + /// array 中从零开始的索引,从此处开始复制。 + public void CopyTo(Array array, int index) + { + ((ICollection)m_LinkedList).CopyTo(array, index); + } + + /// + /// 查找包含指定值的第一个结点。 + /// + /// 要查找的指定值。 + /// 包含指定值的第一个结点。 + public LinkedListNode Find(T value) + { + return m_LinkedList.Find(value); + } + + /// + /// 查找包含指定值的最后一个结点。 + /// + /// 要查找的指定值。 + /// 包含指定值的最后一个结点。 + public LinkedListNode FindLast(T value) + { + return m_LinkedList.FindLast(value); + } + + /// + /// 从链表中移除指定值的第一个匹配项。 + /// + /// 指定值。 + /// 是否移除成功。 + public bool Remove(T value) + { + LinkedListNode node = m_LinkedList.Find(value); + if (node != null) + { + m_LinkedList.Remove(node); + ReleaseNode(node); + return true; + } + + return false; + } + + /// + /// 从链表中移除指定的结点。 + /// + /// 指定的结点。 + public void Remove(LinkedListNode node) + { + m_LinkedList.Remove(node); + ReleaseNode(node); + } + + /// + /// 移除位于链表开头处的结点。 + /// + public void RemoveFirst() + { + LinkedListNode first = m_LinkedList.First; + if (first == null) + { + throw new GameFrameworkException("First is invalid."); + } + + m_LinkedList.RemoveFirst(); + ReleaseNode(first); + } + + /// + /// 移除位于链表结尾处的结点。 + /// + public void RemoveLast() + { + LinkedListNode last = m_LinkedList.Last; + if (last == null) + { + throw new GameFrameworkException("Last is invalid."); + } + + m_LinkedList.RemoveLast(); + ReleaseNode(last); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + public Enumerator GetEnumerator() + { + return new Enumerator(m_LinkedList); + } + + private LinkedListNode AcquireNode(T value) + { + LinkedListNode node = null; + if (m_CachedNodes.Count > 0) + { + node = m_CachedNodes.Dequeue(); + node.Value = value; + } + else + { + node = new LinkedListNode(value); + } + + return node; + } + + private void ReleaseNode(LinkedListNode node) + { + node.Value = default(T); + m_CachedNodes.Enqueue(node); + } + + /// + /// 将值添加到 ICollection`1 的结尾处。 + /// + /// 要添加的值。 + void ICollection.Add(T value) + { + AddLast(value); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 循环访问集合的枚举数。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Enumerator : IEnumerator, IEnumerator + { + private LinkedList.Enumerator m_Enumerator; + + internal Enumerator(LinkedList linkedList) + { + if (linkedList == null) + { + throw new GameFrameworkException("Linked list is invalid."); + } + + m_Enumerator = linkedList.GetEnumerator(); + } + + /// + /// 获取当前结点。 + /// + public T Current + { + get + { + return m_Enumerator.Current; + } + } + + /// + /// 获取当前的枚举数。 + /// + object IEnumerator.Current + { + get + { + return m_Enumerator.Current; + } + } + + /// + /// 清理枚举数。 + /// + public void Dispose() + { + m_Enumerator.Dispose(); + } + + /// + /// 获取下一个结点。 + /// + /// 返回下一个结点。 + public bool MoveNext() + { + return m_Enumerator.MoveNext(); + } + + /// + /// 重置枚举数。 + /// + void IEnumerator.Reset() + { + ((IEnumerator)m_Enumerator).Reset(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedList.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedList.cs.meta new file mode 100644 index 0000000..bb339f9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa2b9dc9d293bcf4ab3a480914abe5fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedListRange.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedListRange.cs new file mode 100644 index 0000000..2e9dbf0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedListRange.cs @@ -0,0 +1,217 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace GameFramework +{ + /// + /// 游戏框架链表范围。 + /// + /// 指定链表范围的元素类型。 + [StructLayout(LayoutKind.Auto)] + public struct GameFrameworkLinkedListRange : IEnumerable, IEnumerable + { + private readonly LinkedListNode m_First; + private readonly LinkedListNode m_Terminal; + + /// + /// 初始化游戏框架链表范围的新实例。 + /// + /// 链表范围的开始结点。 + /// 链表范围的终结标记结点。 + public GameFrameworkLinkedListRange(LinkedListNode first, LinkedListNode terminal) + { + if (first == null || terminal == null || first == terminal) + { + throw new GameFrameworkException("Range is invalid."); + } + + m_First = first; + m_Terminal = terminal; + } + + /// + /// 获取链表范围是否有效。 + /// + public bool IsValid + { + get + { + return m_First != null && m_Terminal != null && m_First != m_Terminal; + } + } + + /// + /// 获取链表范围的开始结点。 + /// + public LinkedListNode First + { + get + { + return m_First; + } + } + + /// + /// 获取链表范围的终结标记结点。 + /// + public LinkedListNode Terminal + { + get + { + return m_Terminal; + } + } + + /// + /// 获取链表范围的结点数量。 + /// + public int Count + { + get + { + if (!IsValid) + { + return 0; + } + + int count = 0; + for (LinkedListNode current = m_First; current != null && current != m_Terminal; current = current.Next) + { + count++; + } + + return count; + } + } + + /// + /// 检查是否包含指定值。 + /// + /// 要检查的值。 + /// 是否包含指定值。 + public bool Contains(T value) + { + for (LinkedListNode current = m_First; current != null && current != m_Terminal; current = current.Next) + { + if (current.Value.Equals(value)) + { + return true; + } + } + + return false; + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + public Enumerator GetEnumerator() + { + return new Enumerator(this); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 循环访问集合的枚举数。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Enumerator : IEnumerator, IEnumerator + { + private readonly GameFrameworkLinkedListRange m_GameFrameworkLinkedListRange; + private LinkedListNode m_Current; + private T m_CurrentValue; + + internal Enumerator(GameFrameworkLinkedListRange range) + { + if (!range.IsValid) + { + throw new GameFrameworkException("Range is invalid."); + } + + m_GameFrameworkLinkedListRange = range; + m_Current = m_GameFrameworkLinkedListRange.m_First; + m_CurrentValue = default(T); + } + + /// + /// 获取当前结点。 + /// + public T Current + { + get + { + return m_CurrentValue; + } + } + + /// + /// 获取当前的枚举数。 + /// + object IEnumerator.Current + { + get + { + return m_CurrentValue; + } + } + + /// + /// 清理枚举数。 + /// + public void Dispose() + { + } + + /// + /// 获取下一个结点。 + /// + /// 返回下一个结点。 + public bool MoveNext() + { + if (m_Current == null || m_Current == m_GameFrameworkLinkedListRange.m_Terminal) + { + return false; + } + + m_CurrentValue = m_Current.Value; + m_Current = m_Current.Next; + return true; + } + + /// + /// 重置枚举数。 + /// + void IEnumerator.Reset() + { + m_Current = m_GameFrameworkLinkedListRange.m_First; + m_CurrentValue = default(T); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedListRange.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedListRange.cs.meta new file mode 100644 index 0000000..32d4bf6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkLinkedListRange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b51de77bba999648b187c0cda831e18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkModule.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkModule.cs new file mode 100644 index 0000000..76f2a95 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkModule.cs @@ -0,0 +1,39 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 游戏框架模块抽象类。 + /// + internal abstract class GameFrameworkModule + { + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal virtual int Priority + { + get + { + return 0; + } + } + + /// + /// 游戏框架模块轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal abstract void Update(float elapseSeconds, float realElapseSeconds); + + /// + /// 关闭并清理游戏框架模块。 + /// + internal abstract void Shutdown(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkModule.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkModule.cs.meta new file mode 100644 index 0000000..2b48e0f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkModule.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fcae23c6b22c681439e41dc75f38fd7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkMultiDictionary.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkMultiDictionary.cs new file mode 100644 index 0000000..3eabc0e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkMultiDictionary.cs @@ -0,0 +1,283 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace GameFramework +{ + /// + /// 游戏框架多值字典类。 + /// + /// 指定多值字典的主键类型。 + /// 指定多值字典的值类型。 + public sealed class GameFrameworkMultiDictionary : IEnumerable>>, IEnumerable + { + private readonly GameFrameworkLinkedList m_LinkedList; + private readonly Dictionary> m_Dictionary; + + /// + /// 初始化游戏框架多值字典类的新实例。 + /// + public GameFrameworkMultiDictionary() + { + m_LinkedList = new GameFrameworkLinkedList(); + m_Dictionary = new Dictionary>(); + } + + /// + /// 获取多值字典中实际包含的主键数量。 + /// + public int Count + { + get + { + return m_Dictionary.Count; + } + } + + /// + /// 获取多值字典中指定主键的范围。 + /// + /// 指定的主键。 + /// 指定主键的范围。 + public GameFrameworkLinkedListRange this[TKey key] + { + get + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + m_Dictionary.TryGetValue(key, out range); + return range; + } + } + + /// + /// 清理多值字典。 + /// + public void Clear() + { + m_Dictionary.Clear(); + m_LinkedList.Clear(); + } + + /// + /// 检查多值字典中是否包含指定主键。 + /// + /// 要检查的主键。 + /// 多值字典中是否包含指定主键。 + public bool Contains(TKey key) + { + return m_Dictionary.ContainsKey(key); + } + + /// + /// 检查多值字典中是否包含指定值。 + /// + /// 要检查的主键。 + /// 要检查的值。 + /// 多值字典中是否包含指定值。 + public bool Contains(TKey key, TValue value) + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + if (m_Dictionary.TryGetValue(key, out range)) + { + return range.Contains(value); + } + + return false; + } + + /// + /// 尝试获取多值字典中指定主键的范围。 + /// + /// 指定的主键。 + /// 指定主键的范围。 + /// 是否获取成功。 + public bool TryGetValue(TKey key, out GameFrameworkLinkedListRange range) + { + return m_Dictionary.TryGetValue(key, out range); + } + + /// + /// 向指定的主键增加指定的值。 + /// + /// 指定的主键。 + /// 指定的值。 + public void Add(TKey key, TValue value) + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + if (m_Dictionary.TryGetValue(key, out range)) + { + m_LinkedList.AddBefore(range.Terminal, value); + } + else + { + LinkedListNode first = m_LinkedList.AddLast(value); + LinkedListNode terminal = m_LinkedList.AddLast(default(TValue)); + m_Dictionary.Add(key, new GameFrameworkLinkedListRange(first, terminal)); + } + } + + /// + /// 从指定的主键中移除指定的值。 + /// + /// 指定的主键。 + /// 指定的值。 + /// 是否移除成功。 + public bool Remove(TKey key, TValue value) + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + if (m_Dictionary.TryGetValue(key, out range)) + { + for (LinkedListNode current = range.First; current != null && current != range.Terminal; current = current.Next) + { + if (current.Value.Equals(value)) + { + if (current == range.First) + { + LinkedListNode next = current.Next; + if (next == range.Terminal) + { + m_LinkedList.Remove(next); + m_Dictionary.Remove(key); + } + else + { + m_Dictionary[key] = new GameFrameworkLinkedListRange(next, range.Terminal); + } + } + + m_LinkedList.Remove(current); + return true; + } + } + } + + return false; + } + + /// + /// 从指定的主键中移除所有的值。 + /// + /// 指定的主键。 + /// 是否移除成功。 + public bool RemoveAll(TKey key) + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + if (m_Dictionary.TryGetValue(key, out range)) + { + m_Dictionary.Remove(key); + + LinkedListNode current = range.First; + while (current != null) + { + LinkedListNode next = current != range.Terminal ? current.Next : null; + m_LinkedList.Remove(current); + current = next; + } + + return true; + } + + return false; + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + public Enumerator GetEnumerator() + { + return new Enumerator(m_Dictionary); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator>> IEnumerable>>.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 循环访问集合的枚举数。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Enumerator : IEnumerator>>, IEnumerator + { + private Dictionary>.Enumerator m_Enumerator; + + internal Enumerator(Dictionary> dictionary) + { + if (dictionary == null) + { + throw new GameFrameworkException("Dictionary is invalid."); + } + + m_Enumerator = dictionary.GetEnumerator(); + } + + /// + /// 获取当前结点。 + /// + public KeyValuePair> Current + { + get + { + return m_Enumerator.Current; + } + } + + /// + /// 获取当前的枚举数。 + /// + object IEnumerator.Current + { + get + { + return m_Enumerator.Current; + } + } + + /// + /// 清理枚举数。 + /// + public void Dispose() + { + m_Enumerator.Dispose(); + } + + /// + /// 获取下一个结点。 + /// + /// 返回下一个结点。 + public bool MoveNext() + { + return m_Enumerator.MoveNext(); + } + + /// + /// 重置枚举数。 + /// + void IEnumerator.Reset() + { + ((IEnumerator>>)m_Enumerator).Reset(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkMultiDictionary.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkMultiDictionary.cs.meta new file mode 100644 index 0000000..cfdd6bf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkMultiDictionary.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: abe0a7a28112b9c4c91e54ca4e7eae5a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkSerializer.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkSerializer.cs new file mode 100644 index 0000000..54547d0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkSerializer.cs @@ -0,0 +1,208 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; +using System.IO; + +namespace GameFramework +{ + /// + /// 游戏框架序列化器基类。 + /// + /// 要序列化的数据类型。 + public abstract class GameFrameworkSerializer + { + private readonly Dictionary m_SerializeCallbacks; + private readonly Dictionary m_DeserializeCallbacks; + private readonly Dictionary m_TryGetValueCallbacks; + private byte m_LatestSerializeCallbackVersion; + + /// + /// 初始化游戏框架序列化器基类的新实例。 + /// + public GameFrameworkSerializer() + { + m_SerializeCallbacks = new Dictionary(); + m_DeserializeCallbacks = new Dictionary(); + m_TryGetValueCallbacks = new Dictionary(); + m_LatestSerializeCallbackVersion = 0; + } + + /// + /// 序列化回调函数。 + /// + /// 目标流。 + /// 要序列化的数据。 + /// 是否序列化数据成功。 + public delegate bool SerializeCallback(Stream stream, T data); + + /// + /// 反序列化回调函数。 + /// + /// 指定流。 + /// 反序列化的数据。 + public delegate T DeserializeCallback(Stream stream); + + /// + /// 尝试从指定流获取指定键的值回调函数。 + /// + /// 指定流。 + /// 指定键。 + /// 指定键的值。 + /// 是否从指定流获取指定键的值成功。 + public delegate bool TryGetValueCallback(Stream stream, string key, out object value); + + /// + /// 注册序列化回调函数。 + /// + /// 序列化回调函数的版本。 + /// 序列化回调函数。 + public void RegisterSerializeCallback(byte version, SerializeCallback callback) + { + if (callback == null) + { + throw new GameFrameworkException("Serialize callback is invalid."); + } + + m_SerializeCallbacks[version] = callback; + if (version > m_LatestSerializeCallbackVersion) + { + m_LatestSerializeCallbackVersion = version; + } + } + + /// + /// 注册反序列化回调函数。 + /// + /// 反序列化回调函数的版本。 + /// 反序列化回调函数。 + public void RegisterDeserializeCallback(byte version, DeserializeCallback callback) + { + if (callback == null) + { + throw new GameFrameworkException("Deserialize callback is invalid."); + } + + m_DeserializeCallbacks[version] = callback; + } + + /// + /// 注册尝试从指定流获取指定键的值回调函数。 + /// + /// 尝试从指定流获取指定键的值回调函数的版本。 + /// 尝试从指定流获取指定键的值回调函数。 + public void RegisterTryGetValueCallback(byte version, TryGetValueCallback callback) + { + if (callback == null) + { + throw new GameFrameworkException("Try get value callback is invalid."); + } + + m_TryGetValueCallbacks[version] = callback; + } + + /// + /// 序列化数据到目标流中。 + /// + /// 目标流。 + /// 要序列化的数据。 + /// 是否序列化数据成功。 + public bool Serialize(Stream stream, T data) + { + if (m_SerializeCallbacks.Count <= 0) + { + throw new GameFrameworkException("No serialize callback registered."); + } + + return Serialize(stream, data, m_LatestSerializeCallbackVersion); + } + + /// + /// 序列化数据到目标流中。 + /// + /// 目标流。 + /// 要序列化的数据。 + /// 序列化回调函数的版本。 + /// 是否序列化数据成功。 + public bool Serialize(Stream stream, T data, byte version) + { + byte[] header = GetHeader(); + stream.WriteByte(header[0]); + stream.WriteByte(header[1]); + stream.WriteByte(header[2]); + stream.WriteByte(version); + SerializeCallback callback = null; + if (!m_SerializeCallbacks.TryGetValue(version, out callback)) + { + throw new GameFrameworkException(Utility.Text.Format("Serialize callback '{0}' is not exist.", version)); + } + + return callback(stream, data); + } + + /// + /// 从指定流反序列化数据。 + /// + /// 指定流。 + /// 反序列化的数据。 + public T Deserialize(Stream stream) + { + byte[] header = GetHeader(); + byte header0 = (byte)stream.ReadByte(); + byte header1 = (byte)stream.ReadByte(); + byte header2 = (byte)stream.ReadByte(); + if (header0 != header[0] || header1 != header[1] || header2 != header[2]) + { + throw new GameFrameworkException(Utility.Text.Format("Header is invalid, need '{0}{1}{2}', current '{3}{4}{5}'.", (char)header[0], (char)header[1], (char)header[2], (char)header0, (char)header1, (char)header2)); + } + + byte version = (byte)stream.ReadByte(); + DeserializeCallback callback = null; + if (!m_DeserializeCallbacks.TryGetValue(version, out callback)) + { + throw new GameFrameworkException(Utility.Text.Format("Deserialize callback '{0}' is not exist.", version)); + } + + return callback(stream); + } + + /// + /// 尝试从指定流获取指定键的值。 + /// + /// 指定流。 + /// 指定键。 + /// 指定键的值。 + /// 是否从指定流获取指定键的值成功。 + public bool TryGetValue(Stream stream, string key, out object value) + { + value = null; + byte[] header = GetHeader(); + byte header0 = (byte)stream.ReadByte(); + byte header1 = (byte)stream.ReadByte(); + byte header2 = (byte)stream.ReadByte(); + if (header0 != header[0] || header1 != header[1] || header2 != header[2]) + { + return false; + } + + byte version = (byte)stream.ReadByte(); + TryGetValueCallback callback = null; + if (!m_TryGetValueCallbacks.TryGetValue(version, out callback)) + { + return false; + } + + return callback(stream, key, out value); + } + + /// + /// 获取数据头标识。 + /// + /// 数据头标识。 + protected abstract byte[] GetHeader(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkSerializer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkSerializer.cs.meta new file mode 100644 index 0000000..cf38f0e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/GameFrameworkSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b232b459d4e22d94dbebbadf54ee5823 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log.meta new file mode 100644 index 0000000..96ceecd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 57ee0dd2c127e484cb25be3a9537417d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.ILogHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.ILogHelper.cs new file mode 100644 index 0000000..e8cd882 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.ILogHelper.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + public static partial class GameFrameworkLog + { + /// + /// 游戏框架日志辅助器接口。 + /// + public interface ILogHelper + { + /// + /// 记录日志。 + /// + /// 游戏框架日志等级。 + /// 日志内容。 + void Log(GameFrameworkLogLevel level, object message); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.ILogHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.ILogHelper.cs.meta new file mode 100644 index 0000000..4d69bee --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.ILogHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3f7268aab6139b48bc311889bf244fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.cs new file mode 100644 index 0000000..d4d9366 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.cs @@ -0,0 +1,2646 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 游戏框架日志类。 + /// + public static partial class GameFrameworkLog + { + private static ILogHelper s_LogHelper = null; + + /// + /// 设置游戏框架日志辅助器。 + /// + /// 要设置的游戏框架日志辅助器。 + public static void SetLogHelper(ILogHelper logHelper) + { + s_LogHelper = logHelper; + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志内容。 + public static void Debug(object message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, message); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志内容。 + public static void Debug(string message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, message); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + public static void Debug(string format, T arg) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + public static void Debug(string format, T1 arg1, T2 arg2) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15)); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Debug, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志内容。 + public static void Info(object message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, message); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志内容。 + public static void Info(string message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, message); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + public static void Info(string format, T arg) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + public static void Info(string format, T1 arg1, T2 arg2) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15)); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Info, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志内容。 + public static void Warning(object message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, message); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志内容。 + public static void Warning(string message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, message); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + public static void Warning(string format, T arg) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + public static void Warning(string format, T1 arg1, T2 arg2) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15)); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Warning, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志内容。 + public static void Error(object message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, message); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志内容。 + public static void Error(string message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, message); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + public static void Error(string format, T arg) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + public static void Error(string format, T1 arg1, T2 arg2) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15)); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Error, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志内容。 + public static void Fatal(object message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, message); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志内容。 + public static void Fatal(string message) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, message); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + public static void Fatal(string format, T arg) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + public static void Fatal(string format, T1 arg1, T2 arg2) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15)); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + if (s_LogHelper == null) + { + return; + } + + s_LogHelper.Log(GameFrameworkLogLevel.Fatal, Utility.Text.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.cs.meta new file mode 100644 index 0000000..0d558c4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLog.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87a0237d37afaeb4488b1f110bd1bf9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLogLevel.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLogLevel.cs new file mode 100644 index 0000000..1afe8a4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLogLevel.cs @@ -0,0 +1,40 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 游戏框架日志等级。 + /// + public enum GameFrameworkLogLevel : byte + { + /// + /// 调试。 + /// + Debug = 0, + + /// + /// 信息。 + /// + Info, + + /// + /// 警告。 + /// + Warning, + + /// + /// 错误。 + /// + Error, + + /// + /// 严重错误。 + /// + Fatal + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLogLevel.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLogLevel.cs.meta new file mode 100644 index 0000000..83eebdd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Log/GameFrameworkLogLevel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ec08a22e22eac54a94422909c7e9912 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool.meta new file mode 100644 index 0000000..3606766 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1838d0faa85527b4d8e2769246cf9b52 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/IReference.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/IReference.cs new file mode 100644 index 0000000..77025c5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/IReference.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 引用接口。 + /// + public interface IReference + { + /// + /// 清理引用。 + /// + void Clear(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/IReference.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/IReference.cs.meta new file mode 100644 index 0000000..7834bcf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/IReference.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f22c43c115dc0d745bf02f2e54b284d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs new file mode 100644 index 0000000..72e023e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs @@ -0,0 +1,202 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework +{ + public static partial class ReferencePool + { + private sealed class ReferenceCollection + { + private readonly Queue m_References; + private readonly Type m_ReferenceType; + private int m_UsingReferenceCount; + private int m_AcquireReferenceCount; + private int m_ReleaseReferenceCount; + private int m_AddReferenceCount; + private int m_RemoveReferenceCount; + + public ReferenceCollection(Type referenceType) + { + m_References = new Queue(); + m_ReferenceType = referenceType; + m_UsingReferenceCount = 0; + m_AcquireReferenceCount = 0; + m_ReleaseReferenceCount = 0; + m_AddReferenceCount = 0; + m_RemoveReferenceCount = 0; + } + + public Type ReferenceType + { + get + { + return m_ReferenceType; + } + } + + public int UnusedReferenceCount + { + get + { + return m_References.Count; + } + } + + public int UsingReferenceCount + { + get + { + return m_UsingReferenceCount; + } + } + + public int AcquireReferenceCount + { + get + { + return m_AcquireReferenceCount; + } + } + + public int ReleaseReferenceCount + { + get + { + return m_ReleaseReferenceCount; + } + } + + public int AddReferenceCount + { + get + { + return m_AddReferenceCount; + } + } + + public int RemoveReferenceCount + { + get + { + return m_RemoveReferenceCount; + } + } + + public T Acquire() where T : class, IReference, new() + { + if (typeof(T) != m_ReferenceType) + { + throw new GameFrameworkException("Type is invalid."); + } + + m_UsingReferenceCount++; + m_AcquireReferenceCount++; + lock (m_References) + { + if (m_References.Count > 0) + { + return (T)m_References.Dequeue(); + } + } + + m_AddReferenceCount++; + return new T(); + } + + public IReference Acquire() + { + m_UsingReferenceCount++; + m_AcquireReferenceCount++; + lock (m_References) + { + if (m_References.Count > 0) + { + return m_References.Dequeue(); + } + } + + m_AddReferenceCount++; + return (IReference)Activator.CreateInstance(m_ReferenceType); + } + + public void Release(IReference reference) + { + reference.Clear(); + lock (m_References) + { + if (m_EnableStrictCheck && m_References.Contains(reference)) + { + throw new GameFrameworkException("The reference has been released."); + } + + m_References.Enqueue(reference); + } + + m_ReleaseReferenceCount++; + m_UsingReferenceCount--; + } + + public void Add(int count) where T : class, IReference, new() + { + if (typeof(T) != m_ReferenceType) + { + throw new GameFrameworkException("Type is invalid."); + } + + lock (m_References) + { + m_AddReferenceCount += count; + while (count-- > 0) + { + m_References.Enqueue(new T()); + } + } + } + + public void Add(int count) + { + lock (m_References) + { + m_AddReferenceCount += count; + while (count-- > 0) + { + m_References.Enqueue((IReference)Activator.CreateInstance(m_ReferenceType)); + } + } + } + + public void Remove(int count) + { + lock (m_References) + { + if (count > m_References.Count) + { + count = m_References.Count; + } + + m_RemoveReferenceCount += count; + while (count-- > 0) + { + m_References.Dequeue(); + } + } + } + + public void RemoveAll() + { + lock (m_References) + { + m_RemoveReferenceCount += m_References.Count; + m_References.Clear(); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs.meta new file mode 100644 index 0000000..db809f9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c19eaae426d076b45987fed1300b9820 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.cs new file mode 100644 index 0000000..b857b2c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.cs @@ -0,0 +1,225 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework +{ + /// + /// 引用池。 + /// + public static partial class ReferencePool + { + private static readonly Dictionary s_ReferenceCollections = new Dictionary(); + private static bool m_EnableStrictCheck = false; + + /// + /// 获取或设置是否开启强制检查。 + /// + public static bool EnableStrictCheck + { + get + { + return m_EnableStrictCheck; + } + set + { + m_EnableStrictCheck = value; + } + } + + /// + /// 获取引用池的数量。 + /// + public static int Count + { + get + { + return s_ReferenceCollections.Count; + } + } + + /// + /// 获取所有引用池的信息。 + /// + /// 所有引用池的信息。 + public static ReferencePoolInfo[] GetAllReferencePoolInfos() + { + int index = 0; + ReferencePoolInfo[] results = null; + + lock (s_ReferenceCollections) + { + results = new ReferencePoolInfo[s_ReferenceCollections.Count]; + foreach (KeyValuePair referenceCollection in s_ReferenceCollections) + { + results[index++] = new ReferencePoolInfo(referenceCollection.Key, referenceCollection.Value.UnusedReferenceCount, referenceCollection.Value.UsingReferenceCount, referenceCollection.Value.AcquireReferenceCount, referenceCollection.Value.ReleaseReferenceCount, referenceCollection.Value.AddReferenceCount, referenceCollection.Value.RemoveReferenceCount); + } + } + + return results; + } + + /// + /// 清除所有引用池。 + /// + public static void ClearAll() + { + lock (s_ReferenceCollections) + { + foreach (KeyValuePair referenceCollection in s_ReferenceCollections) + { + referenceCollection.Value.RemoveAll(); + } + + s_ReferenceCollections.Clear(); + } + } + + /// + /// 从引用池获取引用。 + /// + /// 引用类型。 + /// 引用。 + public static T Acquire() where T : class, IReference, new() + { + return GetReferenceCollection(typeof(T)).Acquire(); + } + + /// + /// 从引用池获取引用。 + /// + /// 引用类型。 + /// 引用。 + public static IReference Acquire(Type referenceType) + { + InternalCheckReferenceType(referenceType); + return GetReferenceCollection(referenceType).Acquire(); + } + + /// + /// 将引用归还引用池。 + /// + /// 引用。 + public static void Release(IReference reference) + { + if (reference == null) + { + throw new GameFrameworkException("Reference is invalid."); + } + + Type referenceType = reference.GetType(); + InternalCheckReferenceType(referenceType); + GetReferenceCollection(referenceType).Release(reference); + } + + /// + /// 向引用池中追加指定数量的引用。 + /// + /// 引用类型。 + /// 追加数量。 + public static void Add(int count) where T : class, IReference, new() + { + GetReferenceCollection(typeof(T)).Add(count); + } + + /// + /// 向引用池中追加指定数量的引用。 + /// + /// 引用类型。 + /// 追加数量。 + public static void Add(Type referenceType, int count) + { + InternalCheckReferenceType(referenceType); + GetReferenceCollection(referenceType).Add(count); + } + + /// + /// 从引用池中移除指定数量的引用。 + /// + /// 引用类型。 + /// 移除数量。 + public static void Remove(int count) where T : class, IReference + { + GetReferenceCollection(typeof(T)).Remove(count); + } + + /// + /// 从引用池中移除指定数量的引用。 + /// + /// 引用类型。 + /// 移除数量。 + public static void Remove(Type referenceType, int count) + { + InternalCheckReferenceType(referenceType); + GetReferenceCollection(referenceType).Remove(count); + } + + /// + /// 从引用池中移除所有的引用。 + /// + /// 引用类型。 + public static void RemoveAll() where T : class, IReference + { + GetReferenceCollection(typeof(T)).RemoveAll(); + } + + /// + /// 从引用池中移除所有的引用。 + /// + /// 引用类型。 + public static void RemoveAll(Type referenceType) + { + InternalCheckReferenceType(referenceType); + GetReferenceCollection(referenceType).RemoveAll(); + } + + private static void InternalCheckReferenceType(Type referenceType) + { + if (!m_EnableStrictCheck) + { + return; + } + + if (referenceType == null) + { + throw new GameFrameworkException("Reference type is invalid."); + } + + if (!referenceType.IsClass || referenceType.IsAbstract) + { + throw new GameFrameworkException("Reference type is not a non-abstract class type."); + } + + if (!typeof(IReference).IsAssignableFrom(referenceType)) + { + throw new GameFrameworkException(Utility.Text.Format("Reference type '{0}' is invalid.", referenceType.FullName)); + } + } + + private static ReferenceCollection GetReferenceCollection(Type referenceType) + { + if (referenceType == null) + { + throw new GameFrameworkException("ReferenceType is invalid."); + } + + ReferenceCollection referenceCollection = null; + lock (s_ReferenceCollections) + { + if (!s_ReferenceCollections.TryGetValue(referenceType, out referenceCollection)) + { + referenceCollection = new ReferenceCollection(referenceType); + s_ReferenceCollections.Add(referenceType, referenceCollection); + } + } + + return referenceCollection; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.cs.meta new file mode 100644 index 0000000..f2d1dc6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55fc0c6295ce30e45b1891bffb35c8e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePoolInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePoolInfo.cs new file mode 100644 index 0000000..617d082 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePoolInfo.cs @@ -0,0 +1,125 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Runtime.InteropServices; + +namespace GameFramework +{ + /// + /// 引用池信息。 + /// + [StructLayout(LayoutKind.Auto)] + public struct ReferencePoolInfo + { + private readonly Type m_Type; + private readonly int m_UnusedReferenceCount; + private readonly int m_UsingReferenceCount; + private readonly int m_AcquireReferenceCount; + private readonly int m_ReleaseReferenceCount; + private readonly int m_AddReferenceCount; + private readonly int m_RemoveReferenceCount; + + /// + /// 初始化引用池信息的新实例。 + /// + /// 引用池类型。 + /// 未使用引用数量。 + /// 正在使用引用数量。 + /// 获取引用数量。 + /// 归还引用数量。 + /// 增加引用数量。 + /// 移除引用数量。 + public ReferencePoolInfo(Type type, int unusedReferenceCount, int usingReferenceCount, int acquireReferenceCount, int releaseReferenceCount, int addReferenceCount, int removeReferenceCount) + { + m_Type = type; + m_UnusedReferenceCount = unusedReferenceCount; + m_UsingReferenceCount = usingReferenceCount; + m_AcquireReferenceCount = acquireReferenceCount; + m_ReleaseReferenceCount = releaseReferenceCount; + m_AddReferenceCount = addReferenceCount; + m_RemoveReferenceCount = removeReferenceCount; + } + + /// + /// 获取引用池类型。 + /// + public Type Type + { + get + { + return m_Type; + } + } + + /// + /// 获取未使用引用数量。 + /// + public int UnusedReferenceCount + { + get + { + return m_UnusedReferenceCount; + } + } + + /// + /// 获取正在使用引用数量。 + /// + public int UsingReferenceCount + { + get + { + return m_UsingReferenceCount; + } + } + + /// + /// 获取获取引用数量。 + /// + public int AcquireReferenceCount + { + get + { + return m_AcquireReferenceCount; + } + } + + /// + /// 获取归还引用数量。 + /// + public int ReleaseReferenceCount + { + get + { + return m_ReleaseReferenceCount; + } + } + + /// + /// 获取增加引用数量。 + /// + public int AddReferenceCount + { + get + { + return m_AddReferenceCount; + } + } + + /// + /// 获取移除引用数量。 + /// + public int RemoveReferenceCount + { + get + { + return m_RemoveReferenceCount; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePoolInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePoolInfo.cs.meta new file mode 100644 index 0000000..334d1c8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/ReferencePool/ReferencePoolInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dddf007c667be0245b073643926ae93e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool.meta new file mode 100644 index 0000000..0df6c22 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d1db06c7ad3bddf469dc83c8ccf9cbec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/ITaskAgent.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/ITaskAgent.cs new file mode 100644 index 0000000..3ec4861 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/ITaskAgent.cs @@ -0,0 +1,53 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 任务代理接口。 + /// + /// 任务类型。 + internal interface ITaskAgent where T : TaskBase + { + /// + /// 获取任务。 + /// + T Task + { + get; + } + + /// + /// 初始化任务代理。 + /// + void Initialize(); + + /// + /// 任务代理轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + void Update(float elapseSeconds, float realElapseSeconds); + + /// + /// 关闭并清理任务代理。 + /// + void Shutdown(); + + /// + /// 开始处理任务。 + /// + /// 要处理的任务。 + /// 开始处理任务的状态。 + StartTaskStatus Start(T task); + + /// + /// 停止正在处理的任务并重置任务代理。 + /// + void Reset(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/ITaskAgent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/ITaskAgent.cs.meta new file mode 100644 index 0000000..c51d878 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/ITaskAgent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9511646fe2a40c54cb5326bf5a78b890 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/StartTaskStatus.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/StartTaskStatus.cs new file mode 100644 index 0000000..7aea6d7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/StartTaskStatus.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 开始处理任务的状态。 + /// + public enum StartTaskStatus : byte + { + /// + /// 可以立刻处理完成此任务。 + /// + Done = 0, + + /// + /// 可以继续处理此任务。 + /// + CanResume, + + /// + /// 不能继续处理此任务,需等待其它任务执行完成。 + /// + HasToWait, + + /// + /// 不能继续处理此任务,出现未知错误。 + /// + UnknownError + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/StartTaskStatus.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/StartTaskStatus.cs.meta new file mode 100644 index 0000000..b48e1c1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/StartTaskStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed1099e3ddb8b9444b197fd468a76775 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskBase.cs new file mode 100644 index 0000000..8c1dc39 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskBase.cs @@ -0,0 +1,137 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 任务基类。 + /// + internal abstract class TaskBase : IReference + { + /// + /// 任务默认优先级。 + /// + public const int DefaultPriority = 0; + + private int m_SerialId; + private string m_Tag; + private int m_Priority; + private object m_UserData; + + private bool m_Done; + + /// + /// 初始化任务基类的新实例。 + /// + public TaskBase() + { + m_SerialId = 0; + m_Tag = null; + m_Priority = DefaultPriority; + m_Done = false; + m_UserData = null; + } + + /// + /// 获取任务的序列编号。 + /// + public int SerialId + { + get + { + return m_SerialId; + } + } + + /// + /// 获取任务的标签。 + /// + public string Tag + { + get + { + return m_Tag; + } + } + + /// + /// 获取任务的优先级。 + /// + public int Priority + { + get + { + return m_Priority; + } + } + + /// + /// 获取任务的用户自定义数据。 + /// + public object UserData + { + get + { + return m_UserData; + } + } + + /// + /// 获取或设置任务是否完成。 + /// + public bool Done + { + get + { + return m_Done; + } + set + { + m_Done = value; + } + } + + /// + /// 获取任务描述。 + /// + public virtual string Description + { + get + { + return null; + } + } + + /// + /// 初始化任务基类。 + /// + /// 任务的序列编号。 + /// 任务的标签。 + /// 任务的优先级。 + /// 任务的用户自定义数据。 + internal void Initialize(int serialId, string tag, int priority, object userData) + { + m_SerialId = serialId; + m_Tag = tag; + m_Priority = priority; + m_UserData = userData; + m_Done = false; + } + + /// + /// 清理任务基类。 + /// + public virtual void Clear() + { + m_SerialId = 0; + m_Tag = null; + m_Priority = DefaultPriority; + m_UserData = null; + m_Done = false; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskBase.cs.meta new file mode 100644 index 0000000..8227afc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65611e2ce2f03544987efbf19294126f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskInfo.cs new file mode 100644 index 0000000..e18f8f2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskInfo.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework +{ + /// + /// 任务信息。 + /// + [StructLayout(LayoutKind.Auto)] + public struct TaskInfo + { + private readonly bool m_IsValid; + private readonly int m_SerialId; + private readonly string m_Tag; + private readonly int m_Priority; + private readonly object m_UserData; + private readonly TaskStatus m_Status; + private readonly string m_Description; + + /// + /// 初始化任务信息的新实例。 + /// + /// 任务的序列编号。 + /// 任务的标签。 + /// 任务的优先级。 + /// 任务的用户自定义数据。 + /// 任务状态。 + /// 任务描述。 + public TaskInfo(int serialId, string tag, int priority, object userData, TaskStatus status, string description) + { + m_IsValid = true; + m_SerialId = serialId; + m_Tag = tag; + m_Priority = priority; + m_UserData = userData; + m_Status = status; + m_Description = description; + } + + /// + /// 获取任务信息是否有效。 + /// + public bool IsValid + { + get + { + return m_IsValid; + } + } + + /// + /// 获取任务的序列编号。 + /// + public int SerialId + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_SerialId; + } + } + + /// + /// 获取任务的标签。 + /// + public string Tag + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Tag; + } + } + + /// + /// 获取任务的优先级。 + /// + public int Priority + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Priority; + } + } + + /// + /// 获取任务的用户自定义数据。 + /// + public object UserData + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_UserData; + } + } + + /// + /// 获取任务状态。 + /// + public TaskStatus Status + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Status; + } + } + + /// + /// 获取任务描述。 + /// + public string Description + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Description; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskInfo.cs.meta new file mode 100644 index 0000000..3f4b703 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5fb34e2035663fc4f8ed986718e668a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskPool.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskPool.cs new file mode 100644 index 0000000..eb60264 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskPool.cs @@ -0,0 +1,444 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework +{ + /// + /// 任务池。 + /// + /// 任务类型。 + internal sealed class TaskPool where T : TaskBase + { + private readonly Stack> m_FreeAgents; + private readonly GameFrameworkLinkedList> m_WorkingAgents; + private readonly GameFrameworkLinkedList m_WaitingTasks; + private bool m_Paused; + + /// + /// 初始化任务池的新实例。 + /// + public TaskPool() + { + m_FreeAgents = new Stack>(); + m_WorkingAgents = new GameFrameworkLinkedList>(); + m_WaitingTasks = new GameFrameworkLinkedList(); + m_Paused = false; + } + + /// + /// 获取或设置任务池是否被暂停。 + /// + public bool Paused + { + get + { + return m_Paused; + } + set + { + m_Paused = value; + } + } + + /// + /// 获取任务代理总数量。 + /// + public int TotalAgentCount + { + get + { + return FreeAgentCount + WorkingAgentCount; + } + } + + /// + /// 获取可用任务代理数量。 + /// + public int FreeAgentCount + { + get + { + return m_FreeAgents.Count; + } + } + + /// + /// 获取工作中任务代理数量。 + /// + public int WorkingAgentCount + { + get + { + return m_WorkingAgents.Count; + } + } + + /// + /// 获取等待任务数量。 + /// + public int WaitingTaskCount + { + get + { + return m_WaitingTasks.Count; + } + } + + /// + /// 任务池轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_Paused) + { + return; + } + + ProcessRunningTasks(elapseSeconds, realElapseSeconds); + ProcessWaitingTasks(elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理任务池。 + /// + public void Shutdown() + { + RemoveAllTasks(); + + while (FreeAgentCount > 0) + { + m_FreeAgents.Pop().Shutdown(); + } + } + + /// + /// 增加任务代理。 + /// + /// 要增加的任务代理。 + public void AddAgent(ITaskAgent agent) + { + if (agent == null) + { + throw new GameFrameworkException("Task agent is invalid."); + } + + agent.Initialize(); + m_FreeAgents.Push(agent); + } + + /// + /// 根据任务的序列编号获取任务的信息。 + /// + /// 要获取信息的任务的序列编号。 + /// 任务的信息。 + public TaskInfo GetTaskInfo(int serialId) + { + foreach (ITaskAgent workingAgent in m_WorkingAgents) + { + T workingTask = workingAgent.Task; + if (workingTask.SerialId == serialId) + { + return new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description); + } + } + + foreach (T waitingTask in m_WaitingTasks) + { + if (waitingTask.SerialId == serialId) + { + return new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description); + } + } + + return default(TaskInfo); + } + + /// + /// 根据任务的标签获取任务的信息。 + /// + /// 要获取信息的任务的标签。 + /// 任务的信息。 + public TaskInfo[] GetTaskInfos(string tag) + { + List results = new List(); + GetTaskInfos(tag, results); + return results.ToArray(); + } + + /// + /// 根据任务的标签获取任务的信息。 + /// + /// 要获取信息的任务的标签。 + /// 任务的信息。 + public void GetTaskInfos(string tag, List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (ITaskAgent workingAgent in m_WorkingAgents) + { + T workingTask = workingAgent.Task; + if (workingTask.Tag == tag) + { + results.Add(new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description)); + } + } + + foreach (T waitingTask in m_WaitingTasks) + { + if (waitingTask.Tag == tag) + { + results.Add(new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description)); + } + } + } + + /// + /// 获取所有任务的信息。 + /// + /// 所有任务的信息。 + public TaskInfo[] GetAllTaskInfos() + { + int index = 0; + TaskInfo[] results = new TaskInfo[m_WorkingAgents.Count + m_WaitingTasks.Count]; + foreach (ITaskAgent workingAgent in m_WorkingAgents) + { + T workingTask = workingAgent.Task; + results[index++] = new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description); + } + + foreach (T waitingTask in m_WaitingTasks) + { + results[index++] = new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description); + } + + return results; + } + + /// + /// 获取所有任务的信息。 + /// + /// 所有任务的信息。 + public void GetAllTaskInfos(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (ITaskAgent workingAgent in m_WorkingAgents) + { + T workingTask = workingAgent.Task; + results.Add(new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description)); + } + + foreach (T waitingTask in m_WaitingTasks) + { + results.Add(new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description)); + } + } + + /// + /// 增加任务。 + /// + /// 要增加的任务。 + public void AddTask(T task) + { + LinkedListNode current = m_WaitingTasks.Last; + while (current != null) + { + if (task.Priority <= current.Value.Priority) + { + break; + } + + current = current.Previous; + } + + if (current != null) + { + m_WaitingTasks.AddAfter(current, task); + } + else + { + m_WaitingTasks.AddFirst(task); + } + } + + /// + /// 根据任务的序列编号移除任务。 + /// + /// 要移除任务的序列编号。 + /// 是否移除任务成功。 + public bool RemoveTask(int serialId) + { + foreach (T task in m_WaitingTasks) + { + if (task.SerialId == serialId) + { + m_WaitingTasks.Remove(task); + ReferencePool.Release(task); + return true; + } + } + + LinkedListNode> currentWorkingAgent = m_WorkingAgents.First; + while (currentWorkingAgent != null) + { + LinkedListNode> next = currentWorkingAgent.Next; + ITaskAgent workingAgent = currentWorkingAgent.Value; + T task = workingAgent.Task; + if (task.SerialId == serialId) + { + workingAgent.Reset(); + m_FreeAgents.Push(workingAgent); + m_WorkingAgents.Remove(currentWorkingAgent); + ReferencePool.Release(task); + return true; + } + + currentWorkingAgent = next; + } + + return false; + } + + /// + /// 根据任务的标签移除任务。 + /// + /// 要移除任务的标签。 + /// 移除任务的数量。 + public int RemoveTasks(string tag) + { + int count = 0; + + LinkedListNode currentWaitingTask = m_WaitingTasks.First; + while (currentWaitingTask != null) + { + LinkedListNode next = currentWaitingTask.Next; + T task = currentWaitingTask.Value; + if (task.Tag == tag) + { + m_WaitingTasks.Remove(currentWaitingTask); + ReferencePool.Release(task); + count++; + } + + currentWaitingTask = next; + } + + LinkedListNode> currentWorkingAgent = m_WorkingAgents.First; + while (currentWorkingAgent != null) + { + LinkedListNode> next = currentWorkingAgent.Next; + ITaskAgent workingAgent = currentWorkingAgent.Value; + T task = workingAgent.Task; + if (task.Tag == tag) + { + workingAgent.Reset(); + m_FreeAgents.Push(workingAgent); + m_WorkingAgents.Remove(currentWorkingAgent); + ReferencePool.Release(task); + count++; + } + + currentWorkingAgent = next; + } + + return count; + } + + /// + /// 移除所有任务。 + /// + /// 移除任务的数量。 + public int RemoveAllTasks() + { + int count = m_WaitingTasks.Count + m_WorkingAgents.Count; + + foreach (T task in m_WaitingTasks) + { + ReferencePool.Release(task); + } + + m_WaitingTasks.Clear(); + + foreach (ITaskAgent workingAgent in m_WorkingAgents) + { + T task = workingAgent.Task; + workingAgent.Reset(); + m_FreeAgents.Push(workingAgent); + ReferencePool.Release(task); + } + + m_WorkingAgents.Clear(); + + return count; + } + + private void ProcessRunningTasks(float elapseSeconds, float realElapseSeconds) + { + LinkedListNode> current = m_WorkingAgents.First; + while (current != null) + { + T task = current.Value.Task; + if (!task.Done) + { + current.Value.Update(elapseSeconds, realElapseSeconds); + current = current.Next; + continue; + } + + LinkedListNode> next = current.Next; + current.Value.Reset(); + m_FreeAgents.Push(current.Value); + m_WorkingAgents.Remove(current); + ReferencePool.Release(task); + current = next; + } + } + + private void ProcessWaitingTasks(float elapseSeconds, float realElapseSeconds) + { + LinkedListNode current = m_WaitingTasks.First; + while (current != null && FreeAgentCount > 0) + { + ITaskAgent agent = m_FreeAgents.Pop(); + LinkedListNode> agentNode = m_WorkingAgents.AddLast(agent); + T task = current.Value; + LinkedListNode next = current.Next; + StartTaskStatus status = agent.Start(task); + if (status == StartTaskStatus.Done || status == StartTaskStatus.HasToWait || status == StartTaskStatus.UnknownError) + { + agent.Reset(); + m_FreeAgents.Push(agent); + m_WorkingAgents.Remove(agentNode); + } + + if (status == StartTaskStatus.Done || status == StartTaskStatus.CanResume || status == StartTaskStatus.UnknownError) + { + m_WaitingTasks.Remove(current); + } + + if (status == StartTaskStatus.Done || status == StartTaskStatus.UnknownError) + { + ReferencePool.Release(task); + } + + current = next; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskPool.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskPool.cs.meta new file mode 100644 index 0000000..d365e07 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskPool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3863d99a1a6c9294bb45e43e97f09b69 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskStatus.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskStatus.cs new file mode 100644 index 0000000..e0060ab --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskStatus.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 任务状态。 + /// + public enum TaskStatus : byte + { + /// + /// 未开始。 + /// + Todo = 0, + + /// + /// 执行中。 + /// + Doing, + + /// + /// 完成。 + /// + Done + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskStatus.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskStatus.cs.meta new file mode 100644 index 0000000..3009876 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/TaskPool/TaskStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 368abbe42754cbd4e8ed2477da58e68c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable.meta new file mode 100644 index 0000000..929addb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b81306bd038bc2f4aa733baec68769ba +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/GenericVariable.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/GenericVariable.cs new file mode 100644 index 0000000..972cca2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/GenericVariable.cs @@ -0,0 +1,89 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + /// + /// 变量。 + /// + /// 变量类型。 + public abstract class Variable : Variable + { + private T m_Value; + + /// + /// 初始化变量的新实例。 + /// + public Variable() + { + m_Value = default(T); + } + + /// + /// 获取变量类型。 + /// + public override Type Type + { + get + { + return typeof(T); + } + } + + /// + /// 获取或设置变量值。 + /// + public T Value + { + get + { + return m_Value; + } + set + { + m_Value = value; + } + } + + /// + /// 获取变量值。 + /// + /// 变量值。 + public override object GetValue() + { + return m_Value; + } + + /// + /// 设置变量值。 + /// + /// 变量值。 + public override void SetValue(object value) + { + m_Value = (T)value; + } + + /// + /// 清理变量值。 + /// + public override void Clear() + { + m_Value = default(T); + } + + /// + /// 获取变量字符串。 + /// + /// 变量字符串。 + public override string ToString() + { + return (m_Value != null) ? m_Value.ToString() : ""; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/GenericVariable.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/GenericVariable.cs.meta new file mode 100644 index 0000000..ce37e5c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/GenericVariable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 274598fb9631cf64fa995078cb26e347 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/Variable.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/Variable.cs new file mode 100644 index 0000000..bd965c1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/Variable.cs @@ -0,0 +1,49 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + /// + /// 变量。 + /// + public abstract class Variable : IReference + { + /// + /// 初始化变量的新实例。 + /// + public Variable() + { + } + + /// + /// 获取变量类型。 + /// + public abstract Type Type + { + get; + } + + /// + /// 获取变量值。 + /// + /// 变量值。 + public abstract object GetValue(); + + /// + /// 设置变量值。 + /// + /// 变量值。 + public abstract void SetValue(object value); + + /// + /// 清理变量值。 + /// + public abstract void Clear(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/Variable.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/Variable.cs.meta new file mode 100644 index 0000000..775ae49 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Variable/Variable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af66e8a42a11cd443b187bffea928329 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version.meta new file mode 100644 index 0000000..04e11a0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b0e6946bfd4818841bc9f458fbcdbd23 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.IVersionHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.IVersionHelper.cs new file mode 100644 index 0000000..d3fce09 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.IVersionHelper.cs @@ -0,0 +1,34 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + public static partial class Version + { + /// + /// 版本号辅助器接口。 + /// + public interface IVersionHelper + { + /// + /// 获取游戏版本号。 + /// + string GameVersion + { + get; + } + + /// + /// 获取内部游戏版本号。 + /// + int InternalGameVersion + { + get; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.IVersionHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.IVersionHelper.cs.meta new file mode 100644 index 0000000..ec49e6a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.IVersionHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: efcb7baff6aba59458c45b4308f69990 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.cs new file mode 100644 index 0000000..1bef04e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 版本号类。 + /// + public static partial class Version + { + private const string GameFrameworkVersionString = "2021.05.31"; + + private static IVersionHelper s_VersionHelper = null; + + /// + /// 获取游戏框架版本号。 + /// + public static string GameFrameworkVersion + { + get + { + return GameFrameworkVersionString; + } + } + + /// + /// 获取游戏版本号。 + /// + public static string GameVersion + { + get + { + if (s_VersionHelper == null) + { + return string.Empty; + } + + return s_VersionHelper.GameVersion; + } + } + + /// + /// 获取内部游戏版本号。 + /// + public static int InternalGameVersion + { + get + { + if (s_VersionHelper == null) + { + return 0; + } + + return s_VersionHelper.InternalGameVersion; + } + } + + /// + /// 设置版本号辅助器。 + /// + /// 要设置的版本号辅助器。 + public static void SetVersionHelper(IVersionHelper versionHelper) + { + s_VersionHelper = versionHelper; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.cs.meta new file mode 100644 index 0000000..69b8f5d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Base/Version/Version.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 591cfaa6702a77945ae7f94b24e67ce9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config.meta new file mode 100644 index 0000000..70fe670 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dd5efb32a44789b44adc617fe5100f37 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.ConfigData.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.ConfigData.cs new file mode 100644 index 0000000..1295029 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.ConfigData.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Config +{ + internal sealed partial class ConfigManager : GameFrameworkModule, IConfigManager + { + [StructLayout(LayoutKind.Auto)] + private struct ConfigData + { + private readonly bool m_BoolValue; + private readonly int m_IntValue; + private readonly float m_FloatValue; + private readonly string m_StringValue; + + public ConfigData(bool boolValue, int intValue, float floatValue, string stringValue) + { + m_BoolValue = boolValue; + m_IntValue = intValue; + m_FloatValue = floatValue; + m_StringValue = stringValue; + } + + public bool BoolValue + { + get + { + return m_BoolValue; + } + } + + public int IntValue + { + get + { + return m_IntValue; + } + } + + public float FloatValue + { + get + { + return m_FloatValue; + } + } + + public string StringValue + { + get + { + return m_StringValue; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.ConfigData.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.ConfigData.cs.meta new file mode 100644 index 0000000..3d4a811 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.ConfigData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5168df0c645d7241b24fb73fc64ff05 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.cs new file mode 100644 index 0000000..7b47e18 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.cs @@ -0,0 +1,487 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.Config +{ + /// + /// 全局配置管理器。 + /// + internal sealed partial class ConfigManager : GameFrameworkModule, IConfigManager + { + private readonly Dictionary m_ConfigDatas; + private readonly DataProvider m_DataProvider; + private IConfigHelper m_ConfigHelper; + + /// + /// 初始化全局配置管理器的新实例。 + /// + public ConfigManager() + { + m_ConfigDatas = new Dictionary(StringComparer.Ordinal); + m_DataProvider = new DataProvider(this); + m_ConfigHelper = null; + } + + /// + /// 获取全局配置项数量。 + /// + public int Count + { + get + { + return m_ConfigDatas.Count; + } + } + + /// + /// 获取缓冲二进制流的大小。 + /// + public int CachedBytesSize + { + get + { + return DataProvider.CachedBytesSize; + } + } + + /// + /// 读取全局配置成功事件。 + /// + public event EventHandler ReadDataSuccess + { + add + { + m_DataProvider.ReadDataSuccess += value; + } + remove + { + m_DataProvider.ReadDataSuccess -= value; + } + } + + /// + /// 读取全局配置失败事件。 + /// + public event EventHandler ReadDataFailure + { + add + { + m_DataProvider.ReadDataFailure += value; + } + remove + { + m_DataProvider.ReadDataFailure -= value; + } + } + + /// + /// 读取全局配置更新事件。 + /// + public event EventHandler ReadDataUpdate + { + add + { + m_DataProvider.ReadDataUpdate += value; + } + remove + { + m_DataProvider.ReadDataUpdate -= value; + } + } + + /// + /// 读取全局配置时加载依赖资源事件。 + /// + public event EventHandler ReadDataDependencyAsset + { + add + { + m_DataProvider.ReadDataDependencyAsset += value; + } + remove + { + m_DataProvider.ReadDataDependencyAsset -= value; + } + } + + /// + /// 全局配置管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理全局配置管理器。 + /// + internal override void Shutdown() + { + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + public void SetResourceManager(IResourceManager resourceManager) + { + m_DataProvider.SetResourceManager(resourceManager); + } + + /// + /// 设置全局配置数据提供者辅助器。 + /// + /// 全局配置数据提供者辅助器。 + public void SetDataProviderHelper(IDataProviderHelper dataProviderHelper) + { + m_DataProvider.SetDataProviderHelper(dataProviderHelper); + } + + /// + /// 设置全局配置辅助器。 + /// + /// 全局配置辅助器。 + public void SetConfigHelper(IConfigHelper configHelper) + { + if (configHelper == null) + { + throw new GameFrameworkException("Config helper is invalid."); + } + + m_ConfigHelper = configHelper; + } + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + public void EnsureCachedBytesSize(int ensureSize) + { + DataProvider.EnsureCachedBytesSize(ensureSize); + } + + /// + /// 释放缓存的二进制流。 + /// + public void FreeCachedBytes() + { + DataProvider.FreeCachedBytes(); + } + + /// + /// 读取全局配置。 + /// + /// 全局配置资源名称。 + public void ReadData(string configAssetName) + { + m_DataProvider.ReadData(configAssetName); + } + + /// + /// 读取全局配置。 + /// + /// 全局配置资源名称。 + /// 加载全局配置资源的优先级。 + public void ReadData(string configAssetName, int priority) + { + m_DataProvider.ReadData(configAssetName, priority); + } + + /// + /// 读取全局配置。 + /// + /// 全局配置资源名称。 + /// 用户自定义数据。 + public void ReadData(string configAssetName, object userData) + { + m_DataProvider.ReadData(configAssetName, userData); + } + + /// + /// 读取全局配置。 + /// + /// 全局配置资源名称。 + /// 加载全局配置资源的优先级。 + /// 用户自定义数据。 + public void ReadData(string configAssetName, int priority, object userData) + { + m_DataProvider.ReadData(configAssetName, priority, userData); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置字符串。 + /// 是否解析全局配置成功。 + public bool ParseData(string configString) + { + return m_DataProvider.ParseData(configString); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置字符串。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public bool ParseData(string configString, object userData) + { + return m_DataProvider.ParseData(configString, userData); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置二进制流。 + /// 是否解析全局配置成功。 + public bool ParseData(byte[] configBytes) + { + return m_DataProvider.ParseData(configBytes); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置二进制流。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public bool ParseData(byte[] configBytes, object userData) + { + return m_DataProvider.ParseData(configBytes, userData); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置二进制流。 + /// 全局配置二进制流的起始位置。 + /// 全局配置二进制流的长度。 + /// 是否解析全局配置成功。 + public bool ParseData(byte[] configBytes, int startIndex, int length) + { + return m_DataProvider.ParseData(configBytes, startIndex, length); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置二进制流。 + /// 全局配置二进制流的起始位置。 + /// 全局配置二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public bool ParseData(byte[] configBytes, int startIndex, int length, object userData) + { + return m_DataProvider.ParseData(configBytes, startIndex, length, userData); + } + + /// + /// 检查是否存在指定全局配置项。 + /// + /// 要检查全局配置项的名称。 + /// 指定的全局配置项是否存在。 + public bool HasConfig(string configName) + { + return GetConfigData(configName).HasValue; + } + + /// + /// 从指定全局配置项中读取布尔值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的布尔值。 + public bool GetBool(string configName) + { + ConfigData? configData = GetConfigData(configName); + if (!configData.HasValue) + { + throw new GameFrameworkException(Utility.Text.Format("Config name '{0}' is not exist.", configName)); + } + + return configData.Value.BoolValue; + } + + /// + /// 从指定全局配置项中读取布尔值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + public bool GetBool(string configName, bool defaultValue) + { + ConfigData? configData = GetConfigData(configName); + return configData.HasValue ? configData.Value.BoolValue : defaultValue; + } + + /// + /// 从指定全局配置项中读取整数值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的整数值。 + public int GetInt(string configName) + { + ConfigData? configData = GetConfigData(configName); + if (!configData.HasValue) + { + throw new GameFrameworkException(Utility.Text.Format("Config name '{0}' is not exist.", configName)); + } + + return configData.Value.IntValue; + } + + /// + /// 从指定全局配置项中读取整数值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的整数值。 + public int GetInt(string configName, int defaultValue) + { + ConfigData? configData = GetConfigData(configName); + return configData.HasValue ? configData.Value.IntValue : defaultValue; + } + + /// + /// 从指定全局配置项中读取浮点数值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的浮点数值。 + public float GetFloat(string configName) + { + ConfigData? configData = GetConfigData(configName); + if (!configData.HasValue) + { + throw new GameFrameworkException(Utility.Text.Format("Config name '{0}' is not exist.", configName)); + } + + return configData.Value.FloatValue; + } + + /// + /// 从指定全局配置项中读取浮点数值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + public float GetFloat(string configName, float defaultValue) + { + ConfigData? configData = GetConfigData(configName); + return configData.HasValue ? configData.Value.FloatValue : defaultValue; + } + + /// + /// 从指定全局配置项中读取字符串值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的字符串值。 + public string GetString(string configName) + { + ConfigData? configData = GetConfigData(configName); + if (!configData.HasValue) + { + throw new GameFrameworkException(Utility.Text.Format("Config name '{0}' is not exist.", configName)); + } + + return configData.Value.StringValue; + } + + /// + /// 从指定全局配置项中读取字符串值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + public string GetString(string configName, string defaultValue) + { + ConfigData? configData = GetConfigData(configName); + return configData.HasValue ? configData.Value.StringValue : defaultValue; + } + + /// + /// 增加指定全局配置项。 + /// + /// 要增加全局配置项的名称。 + /// 全局配置项的值。 + /// 是否增加全局配置项成功。 + public bool AddConfig(string configName, string configValue) + { + bool boolValue = false; + bool.TryParse(configValue, out boolValue); + + int intValue = 0; + int.TryParse(configValue, out intValue); + + float floatValue = 0f; + float.TryParse(configValue, out floatValue); + + return AddConfig(configName, boolValue, intValue, floatValue, configValue); + } + + /// + /// 增加指定全局配置项。 + /// + /// 要增加全局配置项的名称。 + /// 全局配置项布尔值。 + /// 全局配置项整数值。 + /// 全局配置项浮点数值。 + /// 全局配置项字符串值。 + /// 是否增加全局配置项成功。 + public bool AddConfig(string configName, bool boolValue, int intValue, float floatValue, string stringValue) + { + if (HasConfig(configName)) + { + return false; + } + + m_ConfigDatas.Add(configName, new ConfigData(boolValue, intValue, floatValue, stringValue)); + return true; + } + + /// + /// 移除指定全局配置项。 + /// + /// 要移除全局配置项的名称。 + public bool RemoveConfig(string configName) + { + if (!HasConfig(configName)) + { + return false; + } + + return m_ConfigDatas.Remove(configName); + } + + /// + /// 清空所有全局配置项。 + /// + public void RemoveAllConfigs() + { + m_ConfigDatas.Clear(); + } + + private ConfigData? GetConfigData(string configName) + { + if (string.IsNullOrEmpty(configName)) + { + throw new GameFrameworkException("Config name is invalid."); + } + + ConfigData configData = default(ConfigData); + if (m_ConfigDatas.TryGetValue(configName, out configData)) + { + return configData; + } + + return null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.cs.meta new file mode 100644 index 0000000..2e14461 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/ConfigManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f75526da79ea61447bffc03fad48ae51 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigHelper.cs new file mode 100644 index 0000000..d650eea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigHelper.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Config +{ + /// + /// 全局配置辅助器接口。 + /// + public interface IConfigHelper + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigHelper.cs.meta new file mode 100644 index 0000000..ba27fa8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de11ec1c5ca73064d933b66e5671e8fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigManager.cs new file mode 100644 index 0000000..b49f541 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigManager.cs @@ -0,0 +1,160 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; + +namespace GameFramework.Config +{ + /// + /// 全局配置管理器接口。 + /// + public interface IConfigManager : IDataProvider + { + /// + /// 获取全局配置项数量。 + /// + int Count + { + get; + } + + /// + /// 获取缓冲二进制流的大小。 + /// + int CachedBytesSize + { + get; + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + void SetResourceManager(IResourceManager resourceManager); + + /// + /// 设置全局配置数据提供者辅助器。 + /// + /// 全局配置数据提供者辅助器。 + void SetDataProviderHelper(IDataProviderHelper dataProviderHelper); + + /// + /// 设置全局配置辅助器。 + /// + /// 全局配置辅助器。 + void SetConfigHelper(IConfigHelper configHelper); + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + void EnsureCachedBytesSize(int ensureSize); + + /// + /// 释放缓存的二进制流。 + /// + void FreeCachedBytes(); + + /// + /// 检查是否存在指定全局配置项。 + /// + /// 要检查全局配置项的名称。 + /// 指定的全局配置项是否存在。 + bool HasConfig(string configName); + + /// + /// 从指定全局配置项中读取布尔值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的布尔值。 + bool GetBool(string configName); + + /// + /// 从指定全局配置项中读取布尔值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + bool GetBool(string configName, bool defaultValue); + + /// + /// 从指定全局配置项中读取整数值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的整数值。 + int GetInt(string configName); + + /// + /// 从指定全局配置项中读取整数值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的整数值。 + int GetInt(string configName, int defaultValue); + + /// + /// 从指定全局配置项中读取浮点数值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的浮点数值。 + float GetFloat(string configName); + + /// + /// 从指定全局配置项中读取浮点数值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + float GetFloat(string configName, float defaultValue); + + /// + /// 从指定全局配置项中读取字符串值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的字符串值。 + string GetString(string configName); + + /// + /// 从指定全局配置项中读取字符串值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + string GetString(string configName, string defaultValue); + + /// + /// 增加指定全局配置项。 + /// + /// 要增加全局配置项的名称。 + /// 全局配置项的值。 + /// 是否增加全局配置项成功。 + bool AddConfig(string configName, string configValue); + + /// + /// 增加指定全局配置项。 + /// + /// 要增加全局配置项的名称。 + /// 全局配置项布尔值。 + /// 全局配置项整数值。 + /// 全局配置项浮点数值。 + /// 全局配置项字符串值。 + /// 是否增加全局配置项成功。 + bool AddConfig(string configName, bool boolValue, int intValue, float floatValue, string stringValue); + + /// + /// 移除指定全局配置项。 + /// + /// 要移除全局配置项的名称。 + /// 是否移除全局配置项成功。 + bool RemoveConfig(string configName); + + /// + /// 清空所有全局配置项。 + /// + void RemoveAllConfigs(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigManager.cs.meta new file mode 100644 index 0000000..b849ca6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Config/IConfigManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1fdaf5e8ae7a3454ca4e25fe83094ee3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode.meta new file mode 100644 index 0000000..dfb6e95 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bc12fec61d28efd4db83843fe51f1720 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.DataNode.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.DataNode.cs new file mode 100644 index 0000000..57f36d7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.DataNode.cs @@ -0,0 +1,383 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.DataNode +{ + internal sealed partial class DataNodeManager : GameFrameworkModule, IDataNodeManager + { + /// + /// 数据结点。 + /// + private sealed class DataNode : IDataNode, IReference + { + private static readonly DataNode[] EmptyDataNodeArray = new DataNode[] { }; + + private string m_Name; + private Variable m_Data; + private DataNode m_Parent; + private List m_Childs; + + public DataNode() + { + m_Name = null; + m_Data = null; + m_Parent = null; + m_Childs = null; + } + + /// + /// 创建数据结点。 + /// + /// 数据结点名称。 + /// 父数据结点。 + /// 创建的数据结点。 + public static DataNode Create(string name, DataNode parent) + { + if (!IsValidName(name)) + { + throw new GameFrameworkException("Name of data node is invalid."); + } + + DataNode node = ReferencePool.Acquire(); + node.m_Name = name; + node.m_Parent = parent; + return node; + } + + /// + /// 获取数据结点的名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取数据结点的完整名称。 + /// + public string FullName + { + get + { + return m_Parent == null ? m_Name : Utility.Text.Format("{0}{1}{2}", m_Parent.FullName, PathSplitSeparator[0], m_Name); + } + } + + /// + /// 获取父数据结点。 + /// + public IDataNode Parent + { + get + { + return m_Parent; + } + } + + /// + /// 获取子数据结点的数量。 + /// + public int ChildCount + { + get + { + return m_Childs != null ? m_Childs.Count : 0; + } + } + + /// + /// 根据类型获取数据结点的数据。 + /// + /// 要获取的数据类型。 + /// 指定类型的数据。 + public T GetData() where T : Variable + { + return (T)m_Data; + } + + /// + /// 获取数据结点的数据。 + /// + /// 数据结点数据。 + public Variable GetData() + { + return m_Data; + } + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据类型。 + /// 要设置的数据。 + public void SetData(T data) where T : Variable + { + SetData((Variable)data); + } + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据。 + public void SetData(Variable data) + { + if (m_Data != null) + { + ReferencePool.Release(m_Data); + } + + m_Data = data; + } + + /// + /// 根据索引检查是否存在子数据结点。 + /// + /// 子数据结点的索引。 + /// 是否存在子数据结点。 + public bool HasChild(int index) + { + return index >= 0 && index < ChildCount; + } + + /// + /// 根据名称检查是否存在子数据结点。 + /// + /// 子数据结点名称。 + /// 是否存在子数据结点。 + public bool HasChild(string name) + { + if (!IsValidName(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (m_Childs == null) + { + return false; + } + + foreach (DataNode child in m_Childs) + { + if (child.Name == name) + { + return true; + } + } + + return false; + } + + /// + /// 根据索引获取子数据结点。 + /// + /// 子数据结点的索引。 + /// 指定索引的子数据结点,如果索引越界,则返回空。 + public IDataNode GetChild(int index) + { + return index >= 0 && index < ChildCount ? m_Childs[index] : null; + } + + /// + /// 根据名称获取子数据结点。 + /// + /// 子数据结点名称。 + /// 指定名称的子数据结点,如果没有找到,则返回空。 + public IDataNode GetChild(string name) + { + if (!IsValidName(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (m_Childs == null) + { + return null; + } + + foreach (DataNode child in m_Childs) + { + if (child.Name == name) + { + return child; + } + } + + return null; + } + + /// + /// 根据名称获取或增加子数据结点。 + /// + /// 子数据结点名称。 + /// 指定名称的子数据结点,如果对应名称的子数据结点已存在,则返回已存在的子数据结点,否则增加子数据结点。 + public IDataNode GetOrAddChild(string name) + { + DataNode node = (DataNode)GetChild(name); + if (node != null) + { + return node; + } + + node = Create(name, this); + + if (m_Childs == null) + { + m_Childs = new List(); + } + + m_Childs.Add(node); + + return node; + } + + /// + /// 获取所有子数据结点。 + /// + /// 所有子数据结点。 + public IDataNode[] GetAllChild() + { + if (m_Childs == null) + { + return EmptyDataNodeArray; + } + + return m_Childs.ToArray(); + } + + /// + /// 获取所有子数据结点。 + /// + /// 所有子数据结点。 + public void GetAllChild(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + if (m_Childs == null) + { + return; + } + + foreach (DataNode child in m_Childs) + { + results.Add(child); + } + } + + /// + /// 根据索引移除子数据结点。 + /// + /// 子数据结点的索引位置。 + public void RemoveChild(int index) + { + DataNode node = (DataNode)GetChild(index); + if (node == null) + { + return; + } + + m_Childs.Remove(node); + ReferencePool.Release(node); + } + + /// + /// 根据名称移除子数据结点。 + /// + /// 子数据结点名称。 + public void RemoveChild(string name) + { + DataNode node = (DataNode)GetChild(name); + if (node == null) + { + return; + } + + m_Childs.Remove(node); + ReferencePool.Release(node); + } + + public void Clear() + { + if (m_Data != null) + { + ReferencePool.Release(m_Data); + m_Data = null; + } + + if (m_Childs != null) + { + foreach (DataNode child in m_Childs) + { + ReferencePool.Release(child); + } + + m_Childs.Clear(); + } + } + + /// + /// 获取数据结点字符串。 + /// + /// 数据结点字符串。 + public override string ToString() + { + return Utility.Text.Format("{0}: {1}", FullName, ToDataString()); + } + + /// + /// 获取数据字符串。 + /// + /// 数据字符串。 + public string ToDataString() + { + if (m_Data == null) + { + return ""; + } + + return Utility.Text.Format("[{0}] {1}", m_Data.Type.Name, m_Data); + } + + /// + /// 检测数据结点名称是否合法。 + /// + /// 要检测的数据结点名称。 + /// 是否是合法的数据结点名称。 + private static bool IsValidName(string name) + { + if (string.IsNullOrEmpty(name)) + { + return false; + } + + foreach (string pathSplitSeparator in PathSplitSeparator) + { + if (name.Contains(pathSplitSeparator)) + { + return false; + } + } + + return true; + } + + void IReference.Clear() + { + m_Name = null; + m_Parent = null; + Clear(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.DataNode.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.DataNode.cs.meta new file mode 100644 index 0000000..14187ab --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.DataNode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb1bfec1b6dc67b428a15fa1c6c946ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.cs new file mode 100644 index 0000000..263ce07 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.cs @@ -0,0 +1,280 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.DataNode +{ + /// + /// 数据结点管理器。 + /// + internal sealed partial class DataNodeManager : GameFrameworkModule, IDataNodeManager + { + private static readonly string[] EmptyStringArray = new string[] { }; + private static readonly string[] PathSplitSeparator = new string[] { ".", "/", "\\" }; + + private const string RootName = ""; + private DataNode m_Root; + + /// + /// 初始化数据结点管理器的新实例。 + /// + public DataNodeManager() + { + m_Root = DataNode.Create(RootName, null); + } + + /// + /// 获取根数据结点。 + /// + public IDataNode Root + { + get + { + return m_Root; + } + } + + /// + /// 数据结点管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理数据结点管理器。 + /// + internal override void Shutdown() + { + ReferencePool.Release(m_Root); + m_Root = null; + } + + /// + /// 根据类型获取数据结点的数据。 + /// + /// 要获取的数据类型。 + /// 相对于 node 的查找路径。 + /// 指定类型的数据。 + public T GetData(string path) where T : Variable + { + return GetData(path, null); + } + + /// + /// 获取数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 数据结点的数据。 + public Variable GetData(string path) + { + return GetData(path, null); + } + + /// + /// 根据类型获取数据结点的数据。 + /// + /// 要获取的数据类型。 + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定类型的数据。 + public T GetData(string path, IDataNode node) where T : Variable + { + IDataNode current = GetNode(path, node); + if (current == null) + { + throw new GameFrameworkException(Utility.Text.Format("Data node is not exist, path '{0}', node '{1}'.", path, node != null ? node.FullName : string.Empty)); + } + + return current.GetData(); + } + + /// + /// 获取数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 数据结点的数据。 + public Variable GetData(string path, IDataNode node) + { + IDataNode current = GetNode(path, node); + if (current == null) + { + throw new GameFrameworkException(Utility.Text.Format("Data node is not exist, path '{0}', node '{1}'.", path, node != null ? node.FullName : string.Empty)); + } + + return current.GetData(); + } + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据类型。 + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + public void SetData(string path, T data) where T : Variable + { + SetData(path, data, null); + } + + /// + /// 设置数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + public void SetData(string path, Variable data) + { + SetData(path, data, null); + } + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据类型。 + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + /// 查找起始结点。 + public void SetData(string path, T data, IDataNode node) where T : Variable + { + IDataNode current = GetOrAddNode(path, node); + current.SetData(data); + } + + /// + /// 设置数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + /// 查找起始结点。 + public void SetData(string path, Variable data, IDataNode node) + { + IDataNode current = GetOrAddNode(path, node); + current.SetData(data); + } + + /// + /// 获取数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 指定位置的数据结点,如果没有找到,则返回空。 + public IDataNode GetNode(string path) + { + return GetNode(path, null); + } + + /// + /// 获取数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定位置的数据结点,如果没有找到,则返回空。 + public IDataNode GetNode(string path, IDataNode node) + { + IDataNode current = node ?? m_Root; + string[] splitedPath = GetSplitedPath(path); + foreach (string i in splitedPath) + { + current = current.GetChild(i); + if (current == null) + { + return null; + } + } + + return current; + } + + /// + /// 获取或增加数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 指定位置的数据结点,如果没有找到,则创建相应的数据结点。 + public IDataNode GetOrAddNode(string path) + { + return GetOrAddNode(path, null); + } + + /// + /// 获取或增加数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定位置的数据结点,如果没有找到,则增加相应的数据结点。 + public IDataNode GetOrAddNode(string path, IDataNode node) + { + IDataNode current = node ?? m_Root; + string[] splitedPath = GetSplitedPath(path); + foreach (string i in splitedPath) + { + current = current.GetOrAddChild(i); + } + + return current; + } + + /// + /// 移除数据结点。 + /// + /// 相对于 node 的查找路径。 + public void RemoveNode(string path) + { + RemoveNode(path, null); + } + + /// + /// 移除数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + public void RemoveNode(string path, IDataNode node) + { + IDataNode current = node ?? m_Root; + IDataNode parent = current.Parent; + string[] splitedPath = GetSplitedPath(path); + foreach (string i in splitedPath) + { + parent = current; + current = current.GetChild(i); + if (current == null) + { + return; + } + } + + if (parent != null) + { + parent.RemoveChild(current.Name); + } + } + + /// + /// 移除所有数据结点。 + /// + public void Clear() + { + m_Root.Clear(); + } + + /// + /// 数据结点路径切分工具函数。 + /// + /// 要切分的数据结点路径。 + /// 切分后的字符串数组。 + private static string[] GetSplitedPath(string path) + { + if (string.IsNullOrEmpty(path)) + { + return EmptyStringArray; + } + + return path.Split(PathSplitSeparator, StringSplitOptions.RemoveEmptyEntries); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.cs.meta new file mode 100644 index 0000000..7d44506 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/DataNodeManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5a041d45c1a42b478743b0483a1cf1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNode.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNode.cs new file mode 100644 index 0000000..37a990b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNode.cs @@ -0,0 +1,151 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.DataNode +{ + /// + /// 数据结点接口。 + /// + public interface IDataNode + { + /// + /// 获取数据结点的名称。 + /// + string Name + { + get; + } + + /// + /// 获取数据结点的完整名称。 + /// + string FullName + { + get; + } + + /// + /// 获取父数据结点。 + /// + IDataNode Parent + { + get; + } + + /// + /// 获取子数据结点的数量。 + /// + int ChildCount + { + get; + } + + /// + /// 根据类型获取数据结点的数据。 + /// + /// 要获取的数据类型。 + /// 指定类型的数据。 + T GetData() where T : Variable; + + /// + /// 获取数据结点的数据。 + /// + /// 数据结点数据。 + Variable GetData(); + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据类型。 + /// 要设置的数据。 + void SetData(T data) where T : Variable; + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据。 + void SetData(Variable data); + + /// + /// 根据索引检查是否存在子数据结点。 + /// + /// 子数据结点的索引。 + /// 是否存在子数据结点。 + bool HasChild(int index); + + /// + /// 根据名称检查是否存在子数据结点。 + /// + /// 子数据结点名称。 + /// 是否存在子数据结点。 + bool HasChild(string name); + + /// + /// 根据索引获取子数据结点。 + /// + /// 子数据结点的索引。 + /// 指定索引的子数据结点,如果索引越界,则返回空。 + IDataNode GetChild(int index); + + /// + /// 根据名称获取子数据结点。 + /// + /// 子数据结点名称。 + /// 指定名称的子数据结点,如果没有找到,则返回空。 + IDataNode GetChild(string name); + + /// + /// 根据名称获取或增加子数据结点。 + /// + /// 子数据结点名称。 + /// 指定名称的子数据结点,如果对应名称的子数据结点已存在,则返回已存在的子数据结点,否则增加子数据结点。 + IDataNode GetOrAddChild(string name); + + /// + /// 获取所有子数据结点。 + /// + /// 所有子数据结点。 + IDataNode[] GetAllChild(); + + /// + /// 获取所有子数据结点。 + /// + /// 所有子数据结点。 + void GetAllChild(List results); + + /// + /// 根据索引移除子数据结点。 + /// + /// 子数据结点的索引。 + void RemoveChild(int index); + + /// + /// 根据名称移除子数据结点。 + /// + /// 子数据结点名称。 + void RemoveChild(string name); + + /// + /// 移除当前数据结点的数据和所有子数据结点。 + /// + void Clear(); + + /// + /// 获取数据结点字符串。 + /// + /// 数据结点字符串。 + string ToString(); + + /// + /// 获取数据字符串。 + /// + /// 数据字符串。 + string ToDataString(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNode.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNode.cs.meta new file mode 100644 index 0000000..48ee794 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c9fc2c136a4b084c897cf4ac96829ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNodeManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNodeManager.cs new file mode 100644 index 0000000..71b7174 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNodeManager.cs @@ -0,0 +1,135 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.DataNode +{ + /// + /// 数据结点管理器接口。 + /// + public interface IDataNodeManager + { + /// + /// 获取根数据结点。 + /// + IDataNode Root + { + get; + } + + /// + /// 根据类型获取数据结点的数据。 + /// + /// 要获取的数据类型。 + /// 相对于 node 的查找路径。 + /// 指定类型的数据。 + T GetData(string path) where T : Variable; + + /// + /// 获取数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 数据结点的数据。 + Variable GetData(string path); + + /// + /// 根据类型获取数据结点的数据。 + /// + /// 要获取的数据类型。 + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定类型的数据。 + T GetData(string path, IDataNode node) where T : Variable; + + /// + /// 获取数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 数据结点的数据。 + Variable GetData(string path, IDataNode node); + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据类型。 + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + void SetData(string path, T data) where T : Variable; + + /// + /// 设置数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + void SetData(string path, Variable data); + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据类型。 + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + /// 查找起始结点。 + void SetData(string path, T data, IDataNode node) where T : Variable; + + /// + /// 设置数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + /// 查找起始结点。 + void SetData(string path, Variable data, IDataNode node); + + /// + /// 获取数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 指定位置的数据结点,如果没有找到,则返回空。 + IDataNode GetNode(string path); + + /// + /// 获取数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定位置的数据结点,如果没有找到,则返回空。 + IDataNode GetNode(string path, IDataNode node); + + /// + /// 获取或增加数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 指定位置的数据结点,如果没有找到,则创建相应的数据结点。 + IDataNode GetOrAddNode(string path); + + /// + /// 获取或增加数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定位置的数据结点,如果没有找到,则创建相应的数据结点。 + IDataNode GetOrAddNode(string path, IDataNode node); + + /// + /// 移除数据结点。 + /// + /// 相对于 node 的查找路径。 + void RemoveNode(string path); + + /// + /// 移除数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + void RemoveNode(string path, IDataNode node); + + /// + /// 移除所有数据结点。 + /// + void Clear(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNodeManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNodeManager.cs.meta new file mode 100644 index 0000000..f42a61d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataNode/IDataNodeManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99b75476a861ccd4485d535c36498e22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable.meta new file mode 100644 index 0000000..6a2d064 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 60116ee6626486142b20f1aec4f91744 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableBase.cs new file mode 100644 index 0000000..872fbdb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableBase.cs @@ -0,0 +1,304 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; + +namespace GameFramework.DataTable +{ + /// + /// 数据表基类。 + /// + public abstract class DataTableBase : IDataProvider + { + private readonly string m_Name; + private readonly DataProvider m_DataProvider; + + /// + /// 初始化数据表基类的新实例。 + /// + public DataTableBase() + : this(null) + { + } + + /// + /// 初始化数据表基类的新实例。 + /// + /// 数据表名称。 + public DataTableBase(string name) + { + m_Name = name ?? string.Empty; + m_DataProvider = new DataProvider(this); + } + + /// + /// 获取数据表名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取数据表完整名称。 + /// + public string FullName + { + get + { + return new TypeNamePair(Type, m_Name).ToString(); + } + } + + /// + /// 获取数据表行的类型。 + /// + public abstract Type Type + { + get; + } + + /// + /// 获取数据表行数。 + /// + public abstract int Count + { + get; + } + + /// + /// 读取数据表成功事件。 + /// + public event EventHandler ReadDataSuccess + { + add + { + m_DataProvider.ReadDataSuccess += value; + } + remove + { + m_DataProvider.ReadDataSuccess -= value; + } + } + + /// + /// 读取数据表失败事件。 + /// + public event EventHandler ReadDataFailure + { + add + { + m_DataProvider.ReadDataFailure += value; + } + remove + { + m_DataProvider.ReadDataFailure -= value; + } + } + + /// + /// 读取数据表更新事件。 + /// + public event EventHandler ReadDataUpdate + { + add + { + m_DataProvider.ReadDataUpdate += value; + } + remove + { + m_DataProvider.ReadDataUpdate -= value; + } + } + + /// + /// 读取数据表时加载依赖资源事件。 + /// + public event EventHandler ReadDataDependencyAsset + { + add + { + m_DataProvider.ReadDataDependencyAsset += value; + } + remove + { + m_DataProvider.ReadDataDependencyAsset -= value; + } + } + + /// + /// 读取数据表。 + /// + /// 数据表资源名称。 + public void ReadData(string dataTableAssetName) + { + m_DataProvider.ReadData(dataTableAssetName); + } + + /// + /// 读取数据表。 + /// + /// 数据表资源名称。 + /// 加载数据表资源的优先级。 + public void ReadData(string dataTableAssetName, int priority) + { + m_DataProvider.ReadData(dataTableAssetName, priority); + } + + /// + /// 读取数据表。 + /// + /// 数据表资源名称。 + /// 用户自定义数据。 + public void ReadData(string dataTableAssetName, object userData) + { + m_DataProvider.ReadData(dataTableAssetName, userData); + } + + /// + /// 读取数据表。 + /// + /// 数据表资源名称。 + /// 加载数据表资源的优先级。 + /// 用户自定义数据。 + public void ReadData(string dataTableAssetName, int priority, object userData) + { + m_DataProvider.ReadData(dataTableAssetName, priority, userData); + } + + /// + /// 解析数据表。 + /// + /// 要解析的数据表字符串。 + /// 是否解析数据表成功。 + public bool ParseData(string dataTableString) + { + return m_DataProvider.ParseData(dataTableString); + } + + /// + /// 解析数据表。 + /// + /// 要解析的数据表字符串。 + /// 用户自定义数据。 + /// 是否解析数据表成功。 + public bool ParseData(string dataTableString, object userData) + { + return m_DataProvider.ParseData(dataTableString, userData); + } + + /// + /// 解析数据表。 + /// + /// 要解析的数据表二进制流。 + /// 是否解析数据表成功。 + public bool ParseData(byte[] dataTableBytes) + { + return m_DataProvider.ParseData(dataTableBytes); + } + + /// + /// 解析数据表。 + /// + /// 要解析的数据表二进制流。 + /// 用户自定义数据。 + /// 是否解析数据表成功。 + public bool ParseData(byte[] dataTableBytes, object userData) + { + return m_DataProvider.ParseData(dataTableBytes, userData); + } + + /// + /// 解析数据表。 + /// + /// 要解析的数据表二进制流。 + /// 数据表二进制流的起始位置。 + /// 数据表二进制流的长度。 + /// 是否解析数据表成功。 + public bool ParseData(byte[] dataTableBytes, int startIndex, int length) + { + return m_DataProvider.ParseData(dataTableBytes, startIndex, length); + } + + /// + /// 解析数据表。 + /// + /// 要解析的数据表二进制流。 + /// 数据表二进制流的起始位置。 + /// 数据表二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析数据表成功。 + public bool ParseData(byte[] dataTableBytes, int startIndex, int length, object userData) + { + return m_DataProvider.ParseData(dataTableBytes, startIndex, length, userData); + } + + /// + /// 检查是否存在数据表行。 + /// + /// 数据表行的编号。 + /// 是否存在数据表行。 + public abstract bool HasDataRow(int id); + + /// + /// 增加数据表行。 + /// + /// 要解析的数据表行字符串。 + /// 用户自定义数据。 + /// 是否增加数据表行成功。 + public abstract bool AddDataRow(string dataRowString, object userData); + + /// + /// 增加数据表行。 + /// + /// 要解析的数据表行二进制流。 + /// 数据表行二进制流的起始位置。 + /// 数据表行二进制流的长度。 + /// 用户自定义数据。 + /// 是否增加数据表行成功。 + public abstract bool AddDataRow(byte[] dataRowBytes, int startIndex, int length, object userData); + + /// + /// 移除指定数据表行。 + /// + /// 要移除数据表行的编号。 + /// 是否移除数据表行成功。 + public abstract bool RemoveDataRow(int id); + + /// + /// 清空所有数据表行。 + /// + public abstract void RemoveAllDataRows(); + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + internal void SetResourceManager(IResourceManager resourceManager) + { + m_DataProvider.SetResourceManager(resourceManager); + } + + /// + /// 设置数据提供者辅助器。 + /// + /// 数据提供者辅助器。 + internal void SetDataProviderHelper(IDataProviderHelper dataProviderHelper) + { + m_DataProvider.SetDataProviderHelper(dataProviderHelper); + } + + /// + /// 关闭并清理数据表。 + /// + internal abstract void Shutdown(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableBase.cs.meta new file mode 100644 index 0000000..6806a30 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 870439b9509ce794e92461fe9b71c385 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.DataTable.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.DataTable.cs new file mode 100644 index 0000000..4213651 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.DataTable.cs @@ -0,0 +1,524 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace GameFramework.DataTable +{ + internal sealed partial class DataTableManager : GameFrameworkModule, IDataTableManager + { + /// + /// 数据表。 + /// + /// 数据表行的类型。 + private sealed class DataTable : DataTableBase, IDataTable where T : class, IDataRow, new() + { + private readonly Dictionary m_DataSet; + private T m_MinIdDataRow; + private T m_MaxIdDataRow; + + /// + /// 初始化数据表的新实例。 + /// + /// 数据表名称。 + public DataTable(string name) + : base(name) + { + m_DataSet = new Dictionary(); + m_MinIdDataRow = null; + m_MaxIdDataRow = null; + } + + /// + /// 获取数据表行的类型。 + /// + public override Type Type + { + get + { + return typeof(T); + } + } + + /// + /// 获取数据表行数。 + /// + public override int Count + { + get + { + return m_DataSet.Count; + } + } + + /// + /// 获取数据表行。 + /// + /// 数据表行的编号。 + /// 数据表行。 + public T this[int id] + { + get + { + return GetDataRow(id); + } + } + + /// + /// 获取编号最小的数据表行。 + /// + public T MinIdDataRow + { + get + { + return m_MinIdDataRow; + } + } + + /// + /// 获取编号最大的数据表行。 + /// + public T MaxIdDataRow + { + get + { + return m_MaxIdDataRow; + } + } + + /// + /// 检查是否存在数据表行。 + /// + /// 数据表行的编号。 + /// 是否存在数据表行。 + public override bool HasDataRow(int id) + { + return m_DataSet.ContainsKey(id); + } + + /// + /// 检查是否存在数据表行。 + /// + /// 要检查的条件。 + /// 是否存在数据表行。 + public bool HasDataRow(Predicate condition) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + foreach (KeyValuePair dataRow in m_DataSet) + { + if (condition(dataRow.Value)) + { + return true; + } + } + + return false; + } + + /// + /// 获取数据表行。 + /// + /// 数据表行的编号。 + /// 数据表行。 + public T GetDataRow(int id) + { + T dataRow = null; + if (m_DataSet.TryGetValue(id, out dataRow)) + { + return dataRow; + } + + return null; + } + + /// + /// 获取符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 符合条件的数据表行。 + /// 当存在多个符合条件的数据表行时,仅返回第一个符合条件的数据表行。 + public T GetDataRow(Predicate condition) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + foreach (KeyValuePair dataRow in m_DataSet) + { + if (condition(dataRow.Value)) + { + return dataRow.Value; + } + } + + return null; + } + + /// + /// 获取符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 符合条件的数据表行。 + public T[] GetDataRows(Predicate condition) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + List results = new List(); + foreach (KeyValuePair dataRow in m_DataSet) + { + if (condition(dataRow.Value)) + { + results.Add(dataRow.Value); + } + } + + return results.ToArray(); + } + + /// + /// 获取符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 符合条件的数据表行。 + public void GetDataRows(Predicate condition, List results) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair dataRow in m_DataSet) + { + if (condition(dataRow.Value)) + { + results.Add(dataRow.Value); + } + } + } + + /// + /// 获取排序后的数据表行。 + /// + /// 要排序的条件。 + /// 排序后的数据表行。 + public T[] GetDataRows(Comparison comparison) + { + if (comparison == null) + { + throw new GameFrameworkException("Comparison is invalid."); + } + + List results = new List(); + foreach (KeyValuePair dataRow in m_DataSet) + { + results.Add(dataRow.Value); + } + + results.Sort(comparison); + return results.ToArray(); + } + + /// + /// 获取排序后的数据表行。 + /// + /// 要排序的条件。 + /// 排序后的数据表行。 + public void GetDataRows(Comparison comparison, List results) + { + if (comparison == null) + { + throw new GameFrameworkException("Comparison is invalid."); + } + + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair dataRow in m_DataSet) + { + results.Add(dataRow.Value); + } + + results.Sort(comparison); + } + + /// + /// 获取排序后的符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 要排序的条件。 + /// 排序后的符合条件的数据表行。 + public T[] GetDataRows(Predicate condition, Comparison comparison) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + if (comparison == null) + { + throw new GameFrameworkException("Comparison is invalid."); + } + + List results = new List(); + foreach (KeyValuePair dataRow in m_DataSet) + { + if (condition(dataRow.Value)) + { + results.Add(dataRow.Value); + } + } + + results.Sort(comparison); + return results.ToArray(); + } + + /// + /// 获取排序后的符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 要排序的条件。 + /// 排序后的符合条件的数据表行。 + public void GetDataRows(Predicate condition, Comparison comparison, List results) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + if (comparison == null) + { + throw new GameFrameworkException("Comparison is invalid."); + } + + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair dataRow in m_DataSet) + { + if (condition(dataRow.Value)) + { + results.Add(dataRow.Value); + } + } + + results.Sort(comparison); + } + + /// + /// 获取所有数据表行。 + /// + /// 所有数据表行。 + public T[] GetAllDataRows() + { + int index = 0; + T[] results = new T[m_DataSet.Count]; + foreach (KeyValuePair dataRow in m_DataSet) + { + results[index++] = dataRow.Value; + } + + return results; + } + + /// + /// 获取所有数据表行。 + /// + /// 所有数据表行。 + public void GetAllDataRows(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair dataRow in m_DataSet) + { + results.Add(dataRow.Value); + } + } + + /// + /// 增加数据表行。 + /// + /// 要解析的数据表行字符串。 + /// 用户自定义数据。 + /// 是否增加数据表行成功。 + public override bool AddDataRow(string dataRowString, object userData) + { + try + { + T dataRow = new T(); + if (!dataRow.ParseDataRow(dataRowString, userData)) + { + return false; + } + + InternalAddDataRow(dataRow); + return true; + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Can not parse data row string for data table '{0}' with exception '{1}'.", new TypeNamePair(typeof(T), Name), exception), exception); + } + } + + /// + /// 增加数据表行。 + /// + /// 要解析的数据表行二进制流。 + /// 数据表行二进制流的起始位置。 + /// 数据表行二进制流的长度。 + /// 用户自定义数据。 + /// 是否增加数据表行成功。 + public override bool AddDataRow(byte[] dataRowBytes, int startIndex, int length, object userData) + { + try + { + T dataRow = new T(); + if (!dataRow.ParseDataRow(dataRowBytes, startIndex, length, userData)) + { + return false; + } + + InternalAddDataRow(dataRow); + return true; + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Can not parse data row bytes for data table '{0}' with exception '{1}'.", new TypeNamePair(typeof(T), Name), exception), exception); + } + } + + /// + /// 移除指定数据表行。 + /// + /// 要移除数据表行的编号。 + /// 是否移除数据表行成功。 + public override bool RemoveDataRow(int id) + { + if (!HasDataRow(id)) + { + return false; + } + + if (!m_DataSet.Remove(id)) + { + return false; + } + + if (m_MinIdDataRow != null && m_MinIdDataRow.Id == id || m_MaxIdDataRow != null && m_MaxIdDataRow.Id == id) + { + m_MinIdDataRow = null; + m_MaxIdDataRow = null; + foreach (KeyValuePair dataRow in m_DataSet) + { + if (m_MinIdDataRow == null || m_MinIdDataRow.Id > dataRow.Key) + { + m_MinIdDataRow = dataRow.Value; + } + + if (m_MaxIdDataRow == null || m_MaxIdDataRow.Id < dataRow.Key) + { + m_MaxIdDataRow = dataRow.Value; + } + } + } + + return true; + } + + /// + /// 清空所有数据表行。 + /// + public override void RemoveAllDataRows() + { + m_DataSet.Clear(); + m_MinIdDataRow = null; + m_MaxIdDataRow = null; + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + public IEnumerator GetEnumerator() + { + return m_DataSet.Values.GetEnumerator(); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return m_DataSet.Values.GetEnumerator(); + } + + /// + /// 关闭并清理数据表。 + /// + internal override void Shutdown() + { + m_DataSet.Clear(); + } + + private void InternalAddDataRow(T dataRow) + { + if (m_DataSet.ContainsKey(dataRow.Id)) + { + throw new GameFrameworkException(Utility.Text.Format("Already exist '{0}' in data table '{1}'.", dataRow.Id, new TypeNamePair(typeof(T), Name))); + } + + m_DataSet.Add(dataRow.Id, dataRow); + + if (m_MinIdDataRow == null || m_MinIdDataRow.Id > dataRow.Id) + { + m_MinIdDataRow = dataRow; + } + + if (m_MaxIdDataRow == null || m_MaxIdDataRow.Id < dataRow.Id) + { + m_MaxIdDataRow = dataRow; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.DataTable.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.DataTable.cs.meta new file mode 100644 index 0000000..fb21573 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.DataTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d4d09863a21c4b4cad61148995f3a6a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.cs new file mode 100644 index 0000000..2120955 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.cs @@ -0,0 +1,508 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.DataTable +{ + /// + /// 数据表管理器。 + /// + internal sealed partial class DataTableManager : GameFrameworkModule, IDataTableManager + { + private readonly Dictionary m_DataTables; + private IResourceManager m_ResourceManager; + private IDataProviderHelper m_DataProviderHelper; + private IDataTableHelper m_DataTableHelper; + + /// + /// 初始化数据表管理器的新实例。 + /// + public DataTableManager() + { + m_DataTables = new Dictionary(); + m_ResourceManager = null; + m_DataProviderHelper = null; + m_DataTableHelper = null; + } + + /// + /// 获取数据表数量。 + /// + public int Count + { + get + { + return m_DataTables.Count; + } + } + + /// + /// 获取缓冲二进制流的大小。 + /// + public int CachedBytesSize + { + get + { + return DataProvider.CachedBytesSize; + } + } + + /// + /// 数据表管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理数据表管理器。 + /// + internal override void Shutdown() + { + foreach (KeyValuePair dataTable in m_DataTables) + { + dataTable.Value.Shutdown(); + } + + m_DataTables.Clear(); + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + public void SetResourceManager(IResourceManager resourceManager) + { + if (resourceManager == null) + { + throw new GameFrameworkException("Resource manager is invalid."); + } + + m_ResourceManager = resourceManager; + } + + /// + /// 设置数据表数据提供者辅助器。 + /// + /// 数据表数据提供者辅助器。 + public void SetDataProviderHelper(IDataProviderHelper dataProviderHelper) + { + if (dataProviderHelper == null) + { + throw new GameFrameworkException("Data provider helper is invalid."); + } + + m_DataProviderHelper = dataProviderHelper; + } + + /// + /// 设置数据表辅助器。 + /// + /// 数据表辅助器。 + public void SetDataTableHelper(IDataTableHelper dataTableHelper) + { + if (dataTableHelper == null) + { + throw new GameFrameworkException("Data table helper is invalid."); + } + + m_DataTableHelper = dataTableHelper; + } + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + public void EnsureCachedBytesSize(int ensureSize) + { + DataProvider.EnsureCachedBytesSize(ensureSize); + } + + /// + /// 释放缓存的二进制流。 + /// + public void FreeCachedBytes() + { + DataProvider.FreeCachedBytes(); + } + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 是否存在数据表。 + public bool HasDataTable() where T : IDataRow + { + return InternalHasDataTable(new TypeNamePair(typeof(T))); + } + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 是否存在数据表。 + public bool HasDataTable(Type dataRowType) + { + if (dataRowType == null) + { + throw new GameFrameworkException("Data row type is invalid."); + } + + if (!typeof(IDataRow).IsAssignableFrom(dataRowType)) + { + throw new GameFrameworkException(Utility.Text.Format("Data row type '{0}' is invalid.", dataRowType.FullName)); + } + + return InternalHasDataTable(new TypeNamePair(dataRowType)); + } + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否存在数据表。 + public bool HasDataTable(string name) where T : IDataRow + { + return InternalHasDataTable(new TypeNamePair(typeof(T), name)); + } + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否存在数据表。 + public bool HasDataTable(Type dataRowType, string name) + { + if (dataRowType == null) + { + throw new GameFrameworkException("Data row type is invalid."); + } + + if (!typeof(IDataRow).IsAssignableFrom(dataRowType)) + { + throw new GameFrameworkException(Utility.Text.Format("Data row type '{0}' is invalid.", dataRowType.FullName)); + } + + return InternalHasDataTable(new TypeNamePair(dataRowType, name)); + } + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 要获取的数据表。 + public IDataTable GetDataTable() where T : IDataRow + { + return (IDataTable)InternalGetDataTable(new TypeNamePair(typeof(T))); + } + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 要获取的数据表。 + public DataTableBase GetDataTable(Type dataRowType) + { + if (dataRowType == null) + { + throw new GameFrameworkException("Data row type is invalid."); + } + + if (!typeof(IDataRow).IsAssignableFrom(dataRowType)) + { + throw new GameFrameworkException(Utility.Text.Format("Data row type '{0}' is invalid.", dataRowType.FullName)); + } + + return InternalGetDataTable(new TypeNamePair(dataRowType)); + } + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要获取的数据表。 + public IDataTable GetDataTable(string name) where T : IDataRow + { + return (IDataTable)InternalGetDataTable(new TypeNamePair(typeof(T), name)); + } + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要获取的数据表。 + public DataTableBase GetDataTable(Type dataRowType, string name) + { + if (dataRowType == null) + { + throw new GameFrameworkException("Data row type is invalid."); + } + + if (!typeof(IDataRow).IsAssignableFrom(dataRowType)) + { + throw new GameFrameworkException(Utility.Text.Format("Data row type '{0}' is invalid.", dataRowType.FullName)); + } + + return InternalGetDataTable(new TypeNamePair(dataRowType, name)); + } + + /// + /// 获取所有数据表。 + /// + /// 所有数据表。 + public DataTableBase[] GetAllDataTables() + { + int index = 0; + DataTableBase[] results = new DataTableBase[m_DataTables.Count]; + foreach (KeyValuePair dataTable in m_DataTables) + { + results[index++] = dataTable.Value; + } + + return results; + } + + /// + /// 获取所有数据表。 + /// + /// 所有数据表。 + public void GetAllDataTables(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair dataTable in m_DataTables) + { + results.Add(dataTable.Value); + } + } + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 要创建的数据表。 + public IDataTable CreateDataTable() where T : class, IDataRow, new() + { + return CreateDataTable(string.Empty); + } + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 要创建的数据表。 + public DataTableBase CreateDataTable(Type dataRowType) + { + return CreateDataTable(dataRowType, string.Empty); + } + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要创建的数据表。 + public IDataTable CreateDataTable(string name) where T : class, IDataRow, new() + { + if (m_ResourceManager == null) + { + throw new GameFrameworkException("You must set resource manager first."); + } + + if (m_DataProviderHelper == null) + { + throw new GameFrameworkException("You must set data provider helper first."); + } + + TypeNamePair typeNamePair = new TypeNamePair(typeof(T), name); + if (HasDataTable(name)) + { + throw new GameFrameworkException(Utility.Text.Format("Already exist data table '{0}'.", typeNamePair)); + } + + DataTable dataTable = new DataTable(name); + dataTable.SetResourceManager(m_ResourceManager); + dataTable.SetDataProviderHelper(m_DataProviderHelper); + m_DataTables.Add(typeNamePair, dataTable); + return dataTable; + } + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要创建的数据表。 + public DataTableBase CreateDataTable(Type dataRowType, string name) + { + if (m_ResourceManager == null) + { + throw new GameFrameworkException("You must set resource manager first."); + } + + if (m_DataProviderHelper == null) + { + throw new GameFrameworkException("You must set data provider helper first."); + } + + if (dataRowType == null) + { + throw new GameFrameworkException("Data row type is invalid."); + } + + if (!typeof(IDataRow).IsAssignableFrom(dataRowType)) + { + throw new GameFrameworkException(Utility.Text.Format("Data row type '{0}' is invalid.", dataRowType.FullName)); + } + + TypeNamePair typeNamePair = new TypeNamePair(dataRowType, name); + if (HasDataTable(dataRowType, name)) + { + throw new GameFrameworkException(Utility.Text.Format("Already exist data table '{0}'.", typeNamePair)); + } + + Type dataTableType = typeof(DataTable<>).MakeGenericType(dataRowType); + DataTableBase dataTable = (DataTableBase)Activator.CreateInstance(dataTableType, name); + dataTable.SetResourceManager(m_ResourceManager); + dataTable.SetDataProviderHelper(m_DataProviderHelper); + m_DataTables.Add(typeNamePair, dataTable); + return dataTable; + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + public bool DestroyDataTable() where T : IDataRow + { + return InternalDestroyDataTable(new TypeNamePair(typeof(T))); + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(Type dataRowType) + { + if (dataRowType == null) + { + throw new GameFrameworkException("Data row type is invalid."); + } + + if (!typeof(IDataRow).IsAssignableFrom(dataRowType)) + { + throw new GameFrameworkException(Utility.Text.Format("Data row type '{0}' is invalid.", dataRowType.FullName)); + } + + return InternalDestroyDataTable(new TypeNamePair(dataRowType)); + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + public bool DestroyDataTable(string name) where T : IDataRow + { + return InternalDestroyDataTable(new TypeNamePair(typeof(T), name)); + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(Type dataRowType, string name) + { + if (dataRowType == null) + { + throw new GameFrameworkException("Data row type is invalid."); + } + + if (!typeof(IDataRow).IsAssignableFrom(dataRowType)) + { + throw new GameFrameworkException(Utility.Text.Format("Data row type '{0}' is invalid.", dataRowType.FullName)); + } + + return InternalDestroyDataTable(new TypeNamePair(dataRowType, name)); + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 要销毁的数据表。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(IDataTable dataTable) where T : IDataRow + { + if (dataTable == null) + { + throw new GameFrameworkException("Data table is invalid."); + } + + return InternalDestroyDataTable(new TypeNamePair(typeof(T), dataTable.Name)); + } + + /// + /// 销毁数据表。 + /// + /// 要销毁的数据表。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(DataTableBase dataTable) + { + if (dataTable == null) + { + throw new GameFrameworkException("Data table is invalid."); + } + + return InternalDestroyDataTable(new TypeNamePair(dataTable.Type, dataTable.Name)); + } + + private bool InternalHasDataTable(TypeNamePair typeNamePair) + { + return m_DataTables.ContainsKey(typeNamePair); + } + + private DataTableBase InternalGetDataTable(TypeNamePair typeNamePair) + { + DataTableBase dataTable = null; + if (m_DataTables.TryGetValue(typeNamePair, out dataTable)) + { + return dataTable; + } + + return null; + } + + private bool InternalDestroyDataTable(TypeNamePair typeNamePair) + { + DataTableBase dataTable = null; + if (m_DataTables.TryGetValue(typeNamePair, out dataTable)) + { + dataTable.Shutdown(); + return m_DataTables.Remove(typeNamePair); + } + + return false; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.cs.meta new file mode 100644 index 0000000..a49d87d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/DataTableManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ecf8ce2043cbd6d4e902b299899efa6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataRow.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataRow.cs new file mode 100644 index 0000000..3a0fda5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataRow.cs @@ -0,0 +1,41 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.DataTable +{ + /// + /// 数据表行接口。 + /// + public interface IDataRow + { + /// + /// 获取数据表行的编号。 + /// + int Id + { + get; + } + + /// + /// 解析数据表行。 + /// + /// 要解析的数据表行字符串。 + /// 用户自定义数据。 + /// 是否解析数据表行成功。 + bool ParseDataRow(string dataRowString, object userData); + + /// + /// 解析数据表行。 + /// + /// 要解析的数据表行二进制流。 + /// 数据表行二进制流的起始位置。 + /// 数据表行二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析数据表行成功。 + bool ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataRow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataRow.cs.meta new file mode 100644 index 0000000..49ed4c4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataRow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f93da616835c170488f6cec18187a65c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTable.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTable.cs new file mode 100644 index 0000000..71031ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTable.cs @@ -0,0 +1,192 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.DataTable +{ + /// + /// 数据表接口。 + /// + /// 数据表行的类型。 + public interface IDataTable : IEnumerable where T : IDataRow + { + /// + /// 获取数据表名称。 + /// + string Name + { + get; + } + + /// + /// 获取数据表完整名称。 + /// + string FullName + { + get; + } + + /// + /// 获取数据表行的类型。 + /// + Type Type + { + get; + } + + /// + /// 获取数据表行数。 + /// + int Count + { + get; + } + + /// + /// 获取数据表行。 + /// + /// 数据表行的编号。 + /// 数据表行。 + T this[int id] + { + get; + } + + /// + /// 获取编号最小的数据表行。 + /// + T MinIdDataRow + { + get; + } + + /// + /// 获取编号最大的数据表行。 + /// + T MaxIdDataRow + { + get; + } + + /// + /// 检查是否存在数据表行。 + /// + /// 数据表行的编号。 + /// 是否存在数据表行。 + bool HasDataRow(int id); + + /// + /// 检查是否存在数据表行。 + /// + /// 要检查的条件。 + /// 是否存在数据表行。 + bool HasDataRow(Predicate condition); + + /// + /// 获取数据表行。 + /// + /// 数据表行的编号。 + /// 数据表行。 + T GetDataRow(int id); + + /// + /// 获取符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 符合条件的数据表行。 + /// 当存在多个符合条件的数据表行时,仅返回第一个符合条件的数据表行。 + T GetDataRow(Predicate condition); + + /// + /// 获取符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 符合条件的数据表行。 + T[] GetDataRows(Predicate condition); + + /// + /// 获取符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 符合条件的数据表行。 + void GetDataRows(Predicate condition, List results); + + /// + /// 获取排序后的数据表行。 + /// + /// 要排序的条件。 + /// 排序后的数据表行。 + T[] GetDataRows(Comparison comparison); + + /// + /// 获取排序后的数据表行。 + /// + /// 要排序的条件。 + /// 排序后的数据表行。 + void GetDataRows(Comparison comparison, List results); + + /// + /// 获取排序后的符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 要排序的条件。 + /// 排序后的符合条件的数据表行。 + T[] GetDataRows(Predicate condition, Comparison comparison); + + /// + /// 获取排序后的符合条件的数据表行。 + /// + /// 要检查的条件。 + /// 要排序的条件。 + /// 排序后的符合条件的数据表行。 + void GetDataRows(Predicate condition, Comparison comparison, List results); + + /// + /// 获取所有数据表行。 + /// + /// 所有数据表行。 + T[] GetAllDataRows(); + + /// + /// 获取所有数据表行。 + /// + /// 所有数据表行。 + void GetAllDataRows(List results); + + /// + /// 增加数据表行。 + /// + /// 要解析的数据表行字符串。 + /// 用户自定义数据。 + /// 是否增加数据表行成功。 + bool AddDataRow(string dataRowString, object userData); + + /// + /// 增加数据表行。 + /// + /// 要解析的数据表行二进制流。 + /// 数据表行二进制流的起始位置。 + /// 数据表行二进制流的长度。 + /// 用户自定义数据。 + /// 是否增加数据表行成功。 + bool AddDataRow(byte[] dataRowBytes, int startIndex, int length, object userData); + + /// + /// 移除指定数据表行。 + /// + /// 要移除数据表行的编号。 + /// 是否移除数据表行成功。 + bool RemoveDataRow(int id); + + /// + /// 清空所有数据表行。 + /// + void RemoveAllDataRows(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTable.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTable.cs.meta new file mode 100644 index 0000000..876b088 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b1a0ef456f56d24ba07013707dfadd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableHelper.cs new file mode 100644 index 0000000..01e5be5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableHelper.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.DataTable +{ + /// + /// 数据表辅助器接口。 + /// + public interface IDataTableHelper + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableHelper.cs.meta new file mode 100644 index 0000000..3725bc0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84b60de163506284ab39584ea19ab250 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableManager.cs new file mode 100644 index 0000000..ebad68c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableManager.cs @@ -0,0 +1,211 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.DataTable +{ + /// + /// 数据表管理器接口。 + /// + public interface IDataTableManager + { + /// + /// 获取数据表数量。 + /// + int Count + { + get; + } + + /// + /// 获取缓冲二进制流的大小。 + /// + int CachedBytesSize + { + get; + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + void SetResourceManager(IResourceManager resourceManager); + + /// + /// 设置数据表数据提供者辅助器。 + /// + /// 数据表数据提供者辅助器。 + void SetDataProviderHelper(IDataProviderHelper dataProviderHelper); + + /// + /// 设置数据表辅助器。 + /// + /// 数据表辅助器。 + void SetDataTableHelper(IDataTableHelper dataTableHelper); + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + void EnsureCachedBytesSize(int ensureSize); + + /// + /// 释放缓存的二进制流。 + /// + void FreeCachedBytes(); + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 是否存在数据表。 + bool HasDataTable() where T : IDataRow; + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 是否存在数据表。 + bool HasDataTable(Type dataRowType); + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否存在数据表。 + bool HasDataTable(string name) where T : IDataRow; + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否存在数据表。 + bool HasDataTable(Type dataRowType, string name); + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 要获取的数据表。 + IDataTable GetDataTable() where T : IDataRow; + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 要获取的数据表。 + DataTableBase GetDataTable(Type dataRowType); + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要获取的数据表。 + IDataTable GetDataTable(string name) where T : IDataRow; + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要获取的数据表。 + DataTableBase GetDataTable(Type dataRowType, string name); + + /// + /// 获取所有数据表。 + /// + /// 所有数据表。 + DataTableBase[] GetAllDataTables(); + + /// + /// 获取所有数据表。 + /// + /// 所有数据表。 + void GetAllDataTables(List results); + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 要创建的数据表。 + IDataTable CreateDataTable() where T : class, IDataRow, new(); + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 要创建的数据表。 + DataTableBase CreateDataTable(Type dataRowType); + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要创建的数据表。 + IDataTable CreateDataTable(string name) where T : class, IDataRow, new(); + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要创建的数据表。 + DataTableBase CreateDataTable(Type dataRowType, string name); + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 是否销毁数据表成功。 + bool DestroyDataTable() where T : IDataRow; + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 是否销毁数据表成功。 + bool DestroyDataTable(Type dataRowType); + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否销毁数据表成功。 + bool DestroyDataTable(string name) where T : IDataRow; + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否销毁数据表成功。 + bool DestroyDataTable(Type dataRowType, string name); + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 要销毁的数据表。 + /// 是否销毁数据表成功。 + bool DestroyDataTable(IDataTable dataTable) where T : IDataRow; + + /// + /// 销毁数据表。 + /// + /// 要销毁的数据表。 + /// 是否销毁数据表成功。 + bool DestroyDataTable(DataTableBase dataTable); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableManager.cs.meta new file mode 100644 index 0000000..5c59aa9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/DataTable/IDataTableManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ecbc6fe55b71f0c46b2bb6fe1098272c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger.meta new file mode 100644 index 0000000..e85519a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 277c75425b5a43c4d8d51dcb0a25625f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.DebuggerWindowGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.DebuggerWindowGroup.cs new file mode 100644 index 0000000..1364f91 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.DebuggerWindowGroup.cs @@ -0,0 +1,307 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Debugger +{ + internal sealed partial class DebuggerManager : GameFrameworkModule, IDebuggerManager + { + /// + /// 调试器窗口组。 + /// + private sealed class DebuggerWindowGroup : IDebuggerWindowGroup + { + private readonly List> m_DebuggerWindows; + private int m_SelectedIndex; + private string[] m_DebuggerWindowNames; + + public DebuggerWindowGroup() + { + m_DebuggerWindows = new List>(); + m_SelectedIndex = 0; + m_DebuggerWindowNames = null; + } + + /// + /// 获取调试器窗口数量。 + /// + public int DebuggerWindowCount + { + get + { + return m_DebuggerWindows.Count; + } + } + + /// + /// 获取或设置当前选中的调试器窗口索引。 + /// + public int SelectedIndex + { + get + { + return m_SelectedIndex; + } + set + { + m_SelectedIndex = value; + } + } + + /// + /// 获取当前选中的调试器窗口。 + /// + public IDebuggerWindow SelectedWindow + { + get + { + if (m_SelectedIndex >= m_DebuggerWindows.Count) + { + return null; + } + + return m_DebuggerWindows[m_SelectedIndex].Value; + } + } + + /// + /// 初始化调试组。 + /// + /// 初始化调试组参数。 + public void Initialize(params object[] args) + { + } + + /// + /// 关闭调试组。 + /// + public void Shutdown() + { + foreach (KeyValuePair debuggerWindow in m_DebuggerWindows) + { + debuggerWindow.Value.Shutdown(); + } + + m_DebuggerWindows.Clear(); + } + + /// + /// 进入调试器窗口。 + /// + public void OnEnter() + { + SelectedWindow.OnEnter(); + } + + /// + /// 离开调试器窗口。 + /// + public void OnLeave() + { + SelectedWindow.OnLeave(); + } + + /// + /// 调试组轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + SelectedWindow.OnUpdate(elapseSeconds, realElapseSeconds); + } + + /// + /// 调试器窗口绘制。 + /// + public void OnDraw() + { + } + + private void RefreshDebuggerWindowNames() + { + int index = 0; + m_DebuggerWindowNames = new string[m_DebuggerWindows.Count]; + foreach (KeyValuePair debuggerWindow in m_DebuggerWindows) + { + m_DebuggerWindowNames[index++] = debuggerWindow.Key; + } + } + + /// + /// 获取调试组的调试器窗口名称集合。 + /// + public string[] GetDebuggerWindowNames() + { + return m_DebuggerWindowNames; + } + + /// + /// 获取调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要获取的调试器窗口。 + public IDebuggerWindow GetDebuggerWindow(string path) + { + if (string.IsNullOrEmpty(path)) + { + return null; + } + + int pos = path.IndexOf('/'); + if (pos < 0 || pos >= path.Length - 1) + { + return InternalGetDebuggerWindow(path); + } + + string debuggerWindowGroupName = path.Substring(0, pos); + string leftPath = path.Substring(pos + 1); + DebuggerWindowGroup debuggerWindowGroup = (DebuggerWindowGroup)InternalGetDebuggerWindow(debuggerWindowGroupName); + if (debuggerWindowGroup == null) + { + return null; + } + + return debuggerWindowGroup.GetDebuggerWindow(leftPath); + } + + /// + /// 选中调试器窗口。 + /// + /// 调试器窗口路径。 + /// 是否成功选中调试器窗口。 + public bool SelectDebuggerWindow(string path) + { + if (string.IsNullOrEmpty(path)) + { + return false; + } + + int pos = path.IndexOf('/'); + if (pos < 0 || pos >= path.Length - 1) + { + return InternalSelectDebuggerWindow(path); + } + + string debuggerWindowGroupName = path.Substring(0, pos); + string leftPath = path.Substring(pos + 1); + DebuggerWindowGroup debuggerWindowGroup = (DebuggerWindowGroup)InternalGetDebuggerWindow(debuggerWindowGroupName); + if (debuggerWindowGroup == null || !InternalSelectDebuggerWindow(debuggerWindowGroupName)) + { + return false; + } + + return debuggerWindowGroup.SelectDebuggerWindow(leftPath); + } + + /// + /// 注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要注册的调试器窗口。 + public void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow) + { + if (string.IsNullOrEmpty(path)) + { + throw new GameFrameworkException("Path is invalid."); + } + + int pos = path.IndexOf('/'); + if (pos < 0 || pos >= path.Length - 1) + { + if (InternalGetDebuggerWindow(path) != null) + { + throw new GameFrameworkException("Debugger window has been registered."); + } + + m_DebuggerWindows.Add(new KeyValuePair(path, debuggerWindow)); + RefreshDebuggerWindowNames(); + } + else + { + string debuggerWindowGroupName = path.Substring(0, pos); + string leftPath = path.Substring(pos + 1); + DebuggerWindowGroup debuggerWindowGroup = (DebuggerWindowGroup)InternalGetDebuggerWindow(debuggerWindowGroupName); + if (debuggerWindowGroup == null) + { + if (InternalGetDebuggerWindow(debuggerWindowGroupName) != null) + { + throw new GameFrameworkException("Debugger window has been registered, can not create debugger window group."); + } + + debuggerWindowGroup = new DebuggerWindowGroup(); + m_DebuggerWindows.Add(new KeyValuePair(debuggerWindowGroupName, debuggerWindowGroup)); + RefreshDebuggerWindowNames(); + } + + debuggerWindowGroup.RegisterDebuggerWindow(leftPath, debuggerWindow); + } + } + + /// + /// 解除注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 是否解除注册调试器窗口成功。 + public bool UnregisterDebuggerWindow(string path) + { + if (string.IsNullOrEmpty(path)) + { + return false; + } + + int pos = path.IndexOf('/'); + if (pos < 0 || pos >= path.Length - 1) + { + IDebuggerWindow debuggerWindow = InternalGetDebuggerWindow(path); + bool result = m_DebuggerWindows.Remove(new KeyValuePair(path, debuggerWindow)); + debuggerWindow.Shutdown(); + RefreshDebuggerWindowNames(); + return result; + } + + string debuggerWindowGroupName = path.Substring(0, pos); + string leftPath = path.Substring(pos + 1); + DebuggerWindowGroup debuggerWindowGroup = (DebuggerWindowGroup)InternalGetDebuggerWindow(debuggerWindowGroupName); + if (debuggerWindowGroup == null) + { + return false; + } + + return debuggerWindowGroup.UnregisterDebuggerWindow(leftPath); + } + + private IDebuggerWindow InternalGetDebuggerWindow(string name) + { + foreach (KeyValuePair debuggerWindow in m_DebuggerWindows) + { + if (debuggerWindow.Key == name) + { + return debuggerWindow.Value; + } + } + + return null; + } + + private bool InternalSelectDebuggerWindow(string name) + { + for (int i = 0; i < m_DebuggerWindows.Count; i++) + { + if (m_DebuggerWindows[i].Key == name) + { + m_SelectedIndex = i; + return true; + } + } + + return false; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.DebuggerWindowGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.DebuggerWindowGroup.cs.meta new file mode 100644 index 0000000..20ba25a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.DebuggerWindowGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f885a6c2dc9abf746ae25168560f2f96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.cs new file mode 100644 index 0000000..5623ce4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.cs @@ -0,0 +1,141 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Debugger +{ + /// + /// 调试器管理器。 + /// + internal sealed partial class DebuggerManager : GameFrameworkModule, IDebuggerManager + { + private readonly DebuggerWindowGroup m_DebuggerWindowRoot; + private bool m_ActiveWindow; + + /// + /// 初始化调试器管理器的新实例。 + /// + public DebuggerManager() + { + m_DebuggerWindowRoot = new DebuggerWindowGroup(); + m_ActiveWindow = false; + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return -1; + } + } + + /// + /// 获取或设置调试器窗口是否激活。 + /// + public bool ActiveWindow + { + get + { + return m_ActiveWindow; + } + set + { + m_ActiveWindow = value; + } + } + + /// + /// 调试器窗口根结点。 + /// + public IDebuggerWindowGroup DebuggerWindowRoot + { + get + { + return m_DebuggerWindowRoot; + } + } + + /// + /// 调试器管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + if (!m_ActiveWindow) + { + return; + } + + m_DebuggerWindowRoot.OnUpdate(elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理调试器管理器。 + /// + internal override void Shutdown() + { + m_ActiveWindow = false; + m_DebuggerWindowRoot.Shutdown(); + } + + /// + /// 注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要注册的调试器窗口。 + /// 初始化调试器窗口参数。 + public void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow, params object[] args) + { + if (string.IsNullOrEmpty(path)) + { + throw new GameFrameworkException("Path is invalid."); + } + + if (debuggerWindow == null) + { + throw new GameFrameworkException("Debugger window is invalid."); + } + + m_DebuggerWindowRoot.RegisterDebuggerWindow(path, debuggerWindow); + debuggerWindow.Initialize(args); + } + + /// + /// 解除注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 是否解除注册调试器窗口成功。 + public bool UnregisterDebuggerWindow(string path) + { + return m_DebuggerWindowRoot.UnregisterDebuggerWindow(path); + } + + /// + /// 获取调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要获取的调试器窗口。 + public IDebuggerWindow GetDebuggerWindow(string path) + { + return m_DebuggerWindowRoot.GetDebuggerWindow(path); + } + + /// + /// 选中调试器窗口。 + /// + /// 调试器窗口路径。 + /// 是否成功选中调试器窗口。 + public bool SelectDebuggerWindow(string path) + { + return m_DebuggerWindowRoot.SelectDebuggerWindow(path); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.cs.meta new file mode 100644 index 0000000..a67b1e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/DebuggerManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 712e8a50a70e3c242a658f450cdc15f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerManager.cs new file mode 100644 index 0000000..e3cdf76 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerManager.cs @@ -0,0 +1,61 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Debugger +{ + /// + /// 调试器管理器接口。 + /// + public interface IDebuggerManager + { + /// + /// 获取或设置调试器窗口是否激活。 + /// + bool ActiveWindow + { + get; + set; + } + + /// + /// 调试器窗口根结点。 + /// + IDebuggerWindowGroup DebuggerWindowRoot + { + get; + } + + /// + /// 注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要注册的调试器窗口。 + /// 初始化调试器窗口参数。 + void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow, params object[] args); + + /// + /// 解除注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 是否解除注册调试器窗口成功。 + bool UnregisterDebuggerWindow(string path); + + /// + /// 获取调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要获取的调试器窗口。 + IDebuggerWindow GetDebuggerWindow(string path); + + /// + /// 选中调试器窗口。 + /// + /// 调试器窗口路径。 + /// 是否成功选中调试器窗口。 + bool SelectDebuggerWindow(string path); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerManager.cs.meta new file mode 100644 index 0000000..bf58293 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56d979b74c2020c4ea642480c660e235 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindow.cs new file mode 100644 index 0000000..5ac5525 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindow.cs @@ -0,0 +1,48 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Debugger +{ + /// + /// 调试器窗口接口。 + /// + public interface IDebuggerWindow + { + /// + /// 初始化调试器窗口。 + /// + /// 初始化调试器窗口参数。 + void Initialize(params object[] args); + + /// + /// 关闭调试器窗口。 + /// + void Shutdown(); + + /// + /// 进入调试器窗口。 + /// + void OnEnter(); + + /// + /// 离开调试器窗口。 + /// + void OnLeave(); + + /// + /// 调试器窗口轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + void OnUpdate(float elapseSeconds, float realElapseSeconds); + + /// + /// 调试器窗口绘制。 + /// + void OnDraw(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindow.cs.meta new file mode 100644 index 0000000..6746c20 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c39cf770217b9734e84af0b3356920ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindowGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindowGroup.cs new file mode 100644 index 0000000..d5d5a7f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindowGroup.cs @@ -0,0 +1,59 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Debugger +{ + /// + /// 调试器窗口组接口。 + /// + public interface IDebuggerWindowGroup : IDebuggerWindow + { + /// + /// 获取调试器窗口数量。 + /// + int DebuggerWindowCount + { + get; + } + + /// + /// 获取或设置当前选中的调试器窗口索引。 + /// + int SelectedIndex + { + get; + set; + } + + /// + /// 获取当前选中的调试器窗口。 + /// + IDebuggerWindow SelectedWindow + { + get; + } + + /// + /// 获取调试组的调试器窗口名称集合。 + /// + string[] GetDebuggerWindowNames(); + + /// + /// 获取调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要获取的调试器窗口。 + IDebuggerWindow GetDebuggerWindow(string path); + + /// + /// 注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要注册的调试器窗口。 + void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindowGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindowGroup.cs.meta new file mode 100644 index 0000000..6b00163 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Debugger/IDebuggerWindowGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: acf16bd9312153e48a3e5137ac884cd0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download.meta new file mode 100644 index 0000000..79a4f57 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7f4de3cf9ebe31c479054c7fa840e09d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/Constant.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/Constant.cs new file mode 100644 index 0000000..63b6014 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/Constant.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载相关常量。 + /// + internal static class Constant + { + /// + /// 默认下载任务优先级。 + /// + internal const int DefaultPriority = 0; + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/Constant.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/Constant.cs.meta new file mode 100644 index 0000000..743db2f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/Constant.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1613a12eaab20454fb34c6f128cbef1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs new file mode 100644 index 0000000..3eb674d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs @@ -0,0 +1,57 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载代理辅助器完成事件。 + /// + public sealed class DownloadAgentHelperCompleteEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化下载代理辅助器完成事件的新实例。 + /// + public DownloadAgentHelperCompleteEventArgs() + { + Length = 0L; + } + + /// + /// 获取下载的数据大小。 + /// + public long Length + { + get; + private set; + } + + /// + /// 创建下载代理辅助器完成事件。 + /// + /// 下载的数据大小。 + /// 创建的下载代理辅助器完成事件。 + public static DownloadAgentHelperCompleteEventArgs Create(long length) + { + if (length < 0L) + { + throw new GameFrameworkException("Length is invalid."); + } + + DownloadAgentHelperCompleteEventArgs downloadAgentHelperCompleteEventArgs = ReferencePool.Acquire(); + downloadAgentHelperCompleteEventArgs.Length = length; + return downloadAgentHelperCompleteEventArgs; + } + + /// + /// 清理下载代理辅助器完成事件。 + /// + public override void Clear() + { + Length = 0L; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs.meta new file mode 100644 index 0000000..019e176 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4076433d439b2ed46a338187582b69b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperErrorEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperErrorEventArgs.cs new file mode 100644 index 0000000..36d2813 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperErrorEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载代理辅助器错误事件。 + /// + public sealed class DownloadAgentHelperErrorEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化下载代理辅助器错误事件的新实例。 + /// + public DownloadAgentHelperErrorEventArgs() + { + DeleteDownloading = false; + ErrorMessage = null; + } + + /// + /// 获取是否需要删除正在下载的文件。 + /// + public bool DeleteDownloading + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建下载代理辅助器错误事件。 + /// + /// 是否需要删除正在下载的文件。 + /// 错误信息。 + /// 创建的下载代理辅助器错误事件。 + public static DownloadAgentHelperErrorEventArgs Create(bool deleteDownloading, string errorMessage) + { + DownloadAgentHelperErrorEventArgs downloadAgentHelperErrorEventArgs = ReferencePool.Acquire(); + downloadAgentHelperErrorEventArgs.DeleteDownloading = deleteDownloading; + downloadAgentHelperErrorEventArgs.ErrorMessage = errorMessage; + return downloadAgentHelperErrorEventArgs; + } + + /// + /// 清理下载代理辅助器错误事件。 + /// + public override void Clear() + { + DeleteDownloading = false; + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperErrorEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperErrorEventArgs.cs.meta new file mode 100644 index 0000000..c9c0c67 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperErrorEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b96229b98c9a8642951214489743187 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs new file mode 100644 index 0000000..3b8f4cc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs @@ -0,0 +1,94 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载代理辅助器更新数据流事件。 + /// + public sealed class DownloadAgentHelperUpdateBytesEventArgs : GameFrameworkEventArgs + { + private byte[] m_Bytes; + + /// + /// 初始化下载代理辅助器更新数据流事件的新实例。 + /// + public DownloadAgentHelperUpdateBytesEventArgs() + { + m_Bytes = null; + Offset = 0; + Length = 0; + } + + /// + /// 获取数据流的偏移。 + /// + public int Offset + { + get; + private set; + } + + /// + /// 获取数据流的长度。 + /// + public int Length + { + get; + private set; + } + + /// + /// 创建下载代理辅助器更新数据流事件。 + /// + /// 下载的数据流。 + /// 数据流的偏移。 + /// 数据流的长度。 + /// 创建的下载代理辅助器更新数据流事件。 + public static DownloadAgentHelperUpdateBytesEventArgs Create(byte[] bytes, int offset, int length) + { + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + if (offset < 0 || offset >= bytes.Length) + { + throw new GameFrameworkException("Offset is invalid."); + } + + if (length <= 0 || offset + length > bytes.Length) + { + throw new GameFrameworkException("Length is invalid."); + } + + DownloadAgentHelperUpdateBytesEventArgs downloadAgentHelperUpdateBytesEventArgs = ReferencePool.Acquire(); + downloadAgentHelperUpdateBytesEventArgs.m_Bytes = bytes; + downloadAgentHelperUpdateBytesEventArgs.Offset = offset; + downloadAgentHelperUpdateBytesEventArgs.Length = length; + return downloadAgentHelperUpdateBytesEventArgs; + } + + /// + /// 清理下载代理辅助器更新数据流事件。 + /// + public override void Clear() + { + m_Bytes = null; + Offset = 0; + Length = 0; + } + + /// + /// 获取下载的数据流。 + /// + public byte[] GetBytes() + { + return m_Bytes; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs.meta new file mode 100644 index 0000000..3a45f45 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 383456b63d366464a98963b63bd40c08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs new file mode 100644 index 0000000..176c7e8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs @@ -0,0 +1,57 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载代理辅助器更新数据大小事件。 + /// + public sealed class DownloadAgentHelperUpdateLengthEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化下载代理辅助器更新数据大小事件的新实例。 + /// + public DownloadAgentHelperUpdateLengthEventArgs() + { + DeltaLength = 0; + } + + /// + /// 获取下载的增量数据大小。 + /// + public int DeltaLength + { + get; + private set; + } + + /// + /// 创建下载代理辅助器更新数据大小事件。 + /// + /// 下载的增量数据大小。 + /// 创建的下载代理辅助器更新数据大小事件。 + public static DownloadAgentHelperUpdateLengthEventArgs Create(int deltaLength) + { + if (deltaLength <= 0) + { + throw new GameFrameworkException("Delta length is invalid."); + } + + DownloadAgentHelperUpdateLengthEventArgs downloadAgentHelperUpdateLengthEventArgs = ReferencePool.Acquire(); + downloadAgentHelperUpdateLengthEventArgs.DeltaLength = deltaLength; + return downloadAgentHelperUpdateLengthEventArgs; + } + + /// + /// 清理下载代理辅助器更新数据大小事件。 + /// + public override void Clear() + { + DeltaLength = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs.meta new file mode 100644 index 0000000..201fd77 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30e54e8d574e7024e826f011ba4aec70 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadFailureEventArgs.cs new file mode 100644 index 0000000..b552323 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadFailureEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载失败事件。 + /// + public sealed class DownloadFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化下载失败事件的新实例。 + /// + public DownloadFailureEventArgs() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取下载任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建下载失败事件。 + /// + /// 下载任务的序列编号。 + /// 下载后存放路径。 + /// 下载地址。 + /// 错误信息。 + /// 用户自定义数据。 + /// 创建的下载失败事件。 + public static DownloadFailureEventArgs Create(int serialId, string downloadPath, string downloadUri, string errorMessage, object userData) + { + DownloadFailureEventArgs downloadFailureEventArgs = ReferencePool.Acquire(); + downloadFailureEventArgs.SerialId = serialId; + downloadFailureEventArgs.DownloadPath = downloadPath; + downloadFailureEventArgs.DownloadUri = downloadUri; + downloadFailureEventArgs.ErrorMessage = errorMessage; + downloadFailureEventArgs.UserData = userData; + return downloadFailureEventArgs; + } + + /// + /// 清理下载失败事件。 + /// + public override void Clear() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadFailureEventArgs.cs.meta new file mode 100644 index 0000000..931b32d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a834668a21a639a45a85ae08c302bb82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadAgent.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadAgent.cs new file mode 100644 index 0000000..20a38ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadAgent.cs @@ -0,0 +1,375 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.IO; + +namespace GameFramework.Download +{ + internal sealed partial class DownloadManager : GameFrameworkModule, IDownloadManager + { + /// + /// 下载代理。 + /// + private sealed class DownloadAgent : ITaskAgent, IDisposable + { + private readonly IDownloadAgentHelper m_Helper; + private DownloadTask m_Task; + private FileStream m_FileStream; + private int m_WaitFlushSize; + private float m_WaitTime; + private long m_StartLength; + private long m_DownloadedLength; + private long m_SavedLength; + private bool m_Disposed; + + public GameFrameworkAction DownloadAgentStart; + public GameFrameworkAction DownloadAgentUpdate; + public GameFrameworkAction DownloadAgentSuccess; + public GameFrameworkAction DownloadAgentFailure; + + /// + /// 初始化下载代理的新实例。 + /// + /// 下载代理辅助器。 + public DownloadAgent(IDownloadAgentHelper downloadAgentHelper) + { + if (downloadAgentHelper == null) + { + throw new GameFrameworkException("Download agent helper is invalid."); + } + + m_Helper = downloadAgentHelper; + m_Task = null; + m_FileStream = null; + m_WaitFlushSize = 0; + m_WaitTime = 0f; + m_StartLength = 0L; + m_DownloadedLength = 0L; + m_SavedLength = 0L; + m_Disposed = false; + + DownloadAgentStart = null; + DownloadAgentUpdate = null; + DownloadAgentSuccess = null; + DownloadAgentFailure = null; + } + + /// + /// 获取下载任务。 + /// + public DownloadTask Task + { + get + { + return m_Task; + } + } + + /// + /// 获取已经等待时间。 + /// + public float WaitTime + { + get + { + return m_WaitTime; + } + } + + /// + /// 获取开始下载时已经存在的大小。 + /// + public long StartLength + { + get + { + return m_StartLength; + } + } + + /// + /// 获取本次已经下载的大小。 + /// + public long DownloadedLength + { + get + { + return m_DownloadedLength; + } + } + + /// + /// 获取当前的大小。 + /// + public long CurrentLength + { + get + { + return m_StartLength + m_DownloadedLength; + } + } + + /// + /// 获取已经存盘的大小。 + /// + public long SavedLength + { + get + { + return m_SavedLength; + } + } + + /// + /// 初始化下载代理。 + /// + public void Initialize() + { + m_Helper.DownloadAgentHelperUpdateBytes += OnDownloadAgentHelperUpdateBytes; + m_Helper.DownloadAgentHelperUpdateLength += OnDownloadAgentHelperUpdateLength; + m_Helper.DownloadAgentHelperComplete += OnDownloadAgentHelperComplete; + m_Helper.DownloadAgentHelperError += OnDownloadAgentHelperError; + } + + /// + /// 下载代理轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_Task.Status == DownloadTaskStatus.Doing) + { + m_WaitTime += realElapseSeconds; + if (m_WaitTime >= m_Task.Timeout) + { + DownloadAgentHelperErrorEventArgs downloadAgentHelperErrorEventArgs = DownloadAgentHelperErrorEventArgs.Create(false, "Timeout"); + OnDownloadAgentHelperError(this, downloadAgentHelperErrorEventArgs); + ReferencePool.Release(downloadAgentHelperErrorEventArgs); + } + } + } + + /// + /// 关闭并清理下载代理。 + /// + public void Shutdown() + { + Dispose(); + + m_Helper.DownloadAgentHelperUpdateBytes -= OnDownloadAgentHelperUpdateBytes; + m_Helper.DownloadAgentHelperUpdateLength -= OnDownloadAgentHelperUpdateLength; + m_Helper.DownloadAgentHelperComplete -= OnDownloadAgentHelperComplete; + m_Helper.DownloadAgentHelperError -= OnDownloadAgentHelperError; + } + + /// + /// 开始处理下载任务。 + /// + /// 要处理的下载任务。 + /// 开始处理任务的状态。 + public StartTaskStatus Start(DownloadTask task) + { + if (task == null) + { + throw new GameFrameworkException("Task is invalid."); + } + + m_Task = task; + + m_Task.Status = DownloadTaskStatus.Doing; + string downloadFile = Utility.Text.Format("{0}.download", m_Task.DownloadPath); + + try + { + if (File.Exists(downloadFile)) + { + m_FileStream = File.OpenWrite(downloadFile); + m_FileStream.Seek(0L, SeekOrigin.End); + m_StartLength = m_SavedLength = m_FileStream.Length; + m_DownloadedLength = 0L; + } + else + { + string directory = Path.GetDirectoryName(m_Task.DownloadPath); + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + m_FileStream = new FileStream(downloadFile, FileMode.Create, FileAccess.Write); + m_StartLength = m_SavedLength = m_DownloadedLength = 0L; + } + + if (DownloadAgentStart != null) + { + DownloadAgentStart(this); + } + + if (m_StartLength > 0L) + { + m_Helper.Download(m_Task.DownloadUri, m_StartLength, m_Task.UserData); + } + else + { + m_Helper.Download(m_Task.DownloadUri, m_Task.UserData); + } + + return StartTaskStatus.CanResume; + } + catch (Exception exception) + { + DownloadAgentHelperErrorEventArgs downloadAgentHelperErrorEventArgs = DownloadAgentHelperErrorEventArgs.Create(false, exception.ToString()); + OnDownloadAgentHelperError(this, downloadAgentHelperErrorEventArgs); + ReferencePool.Release(downloadAgentHelperErrorEventArgs); + return StartTaskStatus.UnknownError; + } + } + + /// + /// 重置下载代理。 + /// + public void Reset() + { + m_Helper.Reset(); + + if (m_FileStream != null) + { + m_FileStream.Close(); + m_FileStream = null; + } + + m_Task = null; + m_WaitFlushSize = 0; + m_WaitTime = 0f; + m_StartLength = 0L; + m_DownloadedLength = 0L; + m_SavedLength = 0L; + } + + /// + /// 释放资源。 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 释放资源。 + /// + /// 释放资源标记。 + private void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_FileStream != null) + { + m_FileStream.Dispose(); + m_FileStream = null; + } + } + + m_Disposed = true; + } + + private void OnDownloadAgentHelperUpdateBytes(object sender, DownloadAgentHelperUpdateBytesEventArgs e) + { + m_WaitTime = 0f; + try + { + m_FileStream.Write(e.GetBytes(), e.Offset, e.Length); + m_WaitFlushSize += e.Length; + m_SavedLength += e.Length; + + if (m_WaitFlushSize >= m_Task.FlushSize) + { + m_FileStream.Flush(); + m_WaitFlushSize = 0; + } + } + catch (Exception exception) + { + DownloadAgentHelperErrorEventArgs downloadAgentHelperErrorEventArgs = DownloadAgentHelperErrorEventArgs.Create(false, exception.ToString()); + OnDownloadAgentHelperError(this, downloadAgentHelperErrorEventArgs); + ReferencePool.Release(downloadAgentHelperErrorEventArgs); + } + } + + private void OnDownloadAgentHelperUpdateLength(object sender, DownloadAgentHelperUpdateLengthEventArgs e) + { + m_WaitTime = 0f; + m_DownloadedLength += e.DeltaLength; + if (DownloadAgentUpdate != null) + { + DownloadAgentUpdate(this, e.DeltaLength); + } + } + + private void OnDownloadAgentHelperComplete(object sender, DownloadAgentHelperCompleteEventArgs e) + { + m_WaitTime = 0f; + m_DownloadedLength = e.Length; + if (m_SavedLength != CurrentLength) + { + throw new GameFrameworkException("Internal download error."); + } + + m_Helper.Reset(); + m_FileStream.Close(); + m_FileStream = null; + + if (File.Exists(m_Task.DownloadPath)) + { + File.Delete(m_Task.DownloadPath); + } + + File.Move(Utility.Text.Format("{0}.download", m_Task.DownloadPath), m_Task.DownloadPath); + + m_Task.Status = DownloadTaskStatus.Done; + + if (DownloadAgentSuccess != null) + { + DownloadAgentSuccess(this, e.Length); + } + + m_Task.Done = true; + } + + private void OnDownloadAgentHelperError(object sender, DownloadAgentHelperErrorEventArgs e) + { + m_Helper.Reset(); + if (m_FileStream != null) + { + m_FileStream.Close(); + m_FileStream = null; + } + + if (e.DeleteDownloading) + { + File.Delete(Utility.Text.Format("{0}.download", m_Task.DownloadPath)); + } + + m_Task.Status = DownloadTaskStatus.Error; + + if (DownloadAgentFailure != null) + { + DownloadAgentFailure(this, e.ErrorMessage); + } + + m_Task.Done = true; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadAgent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadAgent.cs.meta new file mode 100644 index 0000000..2af1410 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadAgent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 013518044dc160b41b342c3a993517ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs new file mode 100644 index 0000000..779f1d0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs @@ -0,0 +1,64 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + internal sealed partial class DownloadManager : GameFrameworkModule, IDownloadManager + { + private sealed partial class DownloadCounter + { + private sealed class DownloadCounterNode : IReference + { + private long m_DeltaLength; + private float m_ElapseSeconds; + + public DownloadCounterNode() + { + m_DeltaLength = 0L; + m_ElapseSeconds = 0f; + } + + public long DeltaLength + { + get + { + return m_DeltaLength; + } + } + + public float ElapseSeconds + { + get + { + return m_ElapseSeconds; + } + } + + public static DownloadCounterNode Create() + { + return ReferencePool.Acquire(); + } + + public void Update(float elapseSeconds, float realElapseSeconds) + { + m_ElapseSeconds += realElapseSeconds; + } + + public void AddDeltaLength(int deltaLength) + { + m_DeltaLength += deltaLength; + } + + public void Clear() + { + m_DeltaLength = 0L; + m_ElapseSeconds = 0f; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs.meta new file mode 100644 index 0000000..b458589 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa316d09b8ad05240a66d6172936916a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.cs new file mode 100644 index 0000000..dfc9b09 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.cs @@ -0,0 +1,170 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + internal sealed partial class DownloadManager : GameFrameworkModule, IDownloadManager + { + private sealed partial class DownloadCounter + { + private readonly GameFrameworkLinkedList m_DownloadCounterNodes; + private float m_UpdateInterval; + private float m_RecordInterval; + private float m_CurrentSpeed; + private float m_Accumulator; + private float m_TimeLeft; + + public DownloadCounter(float updateInterval, float recordInterval) + { + if (updateInterval <= 0f) + { + throw new GameFrameworkException("Update interval is invalid."); + } + + if (recordInterval <= 0f) + { + throw new GameFrameworkException("Record interval is invalid."); + } + + m_DownloadCounterNodes = new GameFrameworkLinkedList(); + m_UpdateInterval = updateInterval; + m_RecordInterval = recordInterval; + Reset(); + } + + public float UpdateInterval + { + get + { + return m_UpdateInterval; + } + set + { + if (value <= 0f) + { + throw new GameFrameworkException("Update interval is invalid."); + } + + m_UpdateInterval = value; + Reset(); + } + } + + public float RecordInterval + { + get + { + return m_RecordInterval; + } + set + { + if (value <= 0f) + { + throw new GameFrameworkException("Record interval is invalid."); + } + + m_RecordInterval = value; + Reset(); + } + } + + public float CurrentSpeed + { + get + { + return m_CurrentSpeed; + } + } + + public void Shutdown() + { + Reset(); + } + + public void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_DownloadCounterNodes.Count <= 0) + { + return; + } + + m_Accumulator += realElapseSeconds; + if (m_Accumulator > m_RecordInterval) + { + m_Accumulator = m_RecordInterval; + } + + m_TimeLeft -= realElapseSeconds; + foreach (DownloadCounterNode downloadCounterNode in m_DownloadCounterNodes) + { + downloadCounterNode.Update(elapseSeconds, realElapseSeconds); + } + + while (m_DownloadCounterNodes.Count > 0) + { + DownloadCounterNode downloadCounterNode = m_DownloadCounterNodes.First.Value; + if (downloadCounterNode.ElapseSeconds < m_RecordInterval) + { + break; + } + + ReferencePool.Release(downloadCounterNode); + m_DownloadCounterNodes.RemoveFirst(); + } + + if (m_DownloadCounterNodes.Count <= 0) + { + Reset(); + return; + } + + if (m_TimeLeft <= 0f) + { + long totalDeltaLength = 0L; + foreach (DownloadCounterNode downloadCounterNode in m_DownloadCounterNodes) + { + totalDeltaLength += downloadCounterNode.DeltaLength; + } + + m_CurrentSpeed = m_Accumulator > 0f ? totalDeltaLength / m_Accumulator : 0f; + m_TimeLeft += m_UpdateInterval; + } + } + + public void RecordDeltaLength(int deltaLength) + { + if (deltaLength <= 0) + { + return; + } + + DownloadCounterNode downloadCounterNode = null; + if (m_DownloadCounterNodes.Count > 0) + { + downloadCounterNode = m_DownloadCounterNodes.Last.Value; + if (downloadCounterNode.ElapseSeconds < m_UpdateInterval) + { + downloadCounterNode.AddDeltaLength(deltaLength); + return; + } + } + + downloadCounterNode = DownloadCounterNode.Create(); + downloadCounterNode.AddDeltaLength(deltaLength); + m_DownloadCounterNodes.AddLast(downloadCounterNode); + } + + private void Reset() + { + m_DownloadCounterNodes.Clear(); + m_CurrentSpeed = 0f; + m_Accumulator = 0f; + m_TimeLeft = 0f; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.cs.meta new file mode 100644 index 0000000..9283035 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadCounter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 666e073ec8292f24397719575dbd310f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTask.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTask.cs new file mode 100644 index 0000000..0132b28 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTask.cs @@ -0,0 +1,143 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + internal sealed partial class DownloadManager : GameFrameworkModule, IDownloadManager + { + /// + /// 下载任务。 + /// + private sealed class DownloadTask : TaskBase + { + private static int s_Serial = 0; + + private DownloadTaskStatus m_Status; + private string m_DownloadPath; + private string m_DownloadUri; + private int m_FlushSize; + private float m_Timeout; + + /// + /// 初始化下载任务的新实例。 + /// + public DownloadTask() + { + m_Status = DownloadTaskStatus.Todo; + m_DownloadPath = null; + m_DownloadUri = null; + m_FlushSize = 0; + m_Timeout = 0f; + } + + /// + /// 获取或设置下载任务的状态。 + /// + public DownloadTaskStatus Status + { + get + { + return m_Status; + } + set + { + m_Status = value; + } + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get + { + return m_DownloadPath; + } + } + + /// + /// 获取原始下载地址。 + /// + public string DownloadUri + { + get + { + return m_DownloadUri; + } + } + + /// + /// 获取将缓冲区写入磁盘的临界大小。 + /// + public int FlushSize + { + get + { + return m_FlushSize; + } + } + + /// + /// 获取下载超时时长,以秒为单位。 + /// + public float Timeout + { + get + { + return m_Timeout; + } + } + + /// + /// 获取下载任务的描述。 + /// + public override string Description + { + get + { + return m_DownloadPath; + } + } + + /// + /// 创建下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 下载任务的优先级。 + /// 将缓冲区写入磁盘的临界大小。 + /// 下载超时时长,以秒为单位。 + /// 用户自定义数据。 + /// 创建的下载任务。 + public static DownloadTask Create(string downloadPath, string downloadUri, string tag, int priority, int flushSize, float timeout, object userData) + { + DownloadTask downloadTask = ReferencePool.Acquire(); + downloadTask.Initialize(++s_Serial, tag, priority, userData); + downloadTask.m_DownloadPath = downloadPath; + downloadTask.m_DownloadUri = downloadUri; + downloadTask.m_FlushSize = flushSize; + downloadTask.m_Timeout = timeout; + return downloadTask; + } + + /// + /// 清理下载任务。 + /// + public override void Clear() + { + base.Clear(); + m_Status = DownloadTaskStatus.Todo; + m_DownloadPath = null; + m_DownloadUri = null; + m_FlushSize = 0; + m_Timeout = 0f; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTask.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTask.cs.meta new file mode 100644 index 0000000..524f2fd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 64ef3f2125c886e40b9bd0141b57756d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTaskStatus.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTaskStatus.cs new file mode 100644 index 0000000..4e3dc19 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTaskStatus.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + internal sealed partial class DownloadManager : GameFrameworkModule, IDownloadManager + { + /// + /// 下载任务的状态。 + /// + private enum DownloadTaskStatus : byte + { + /// + /// 准备下载。 + /// + Todo = 0, + + /// + /// 下载中。 + /// + Doing, + + /// + /// 下载完成。 + /// + Done, + + /// + /// 下载错误。 + /// + Error + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTaskStatus.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTaskStatus.cs.meta new file mode 100644 index 0000000..afc8354 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.DownloadTaskStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 478002d0db913694282b3bd952bbb751 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.cs new file mode 100644 index 0000000..da8b31f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.cs @@ -0,0 +1,486 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Download +{ + /// + /// 下载管理器。 + /// + internal sealed partial class DownloadManager : GameFrameworkModule, IDownloadManager + { + private const int OneMegaBytes = 1024 * 1024; + + private readonly TaskPool m_TaskPool; + private readonly DownloadCounter m_DownloadCounter; + private int m_FlushSize; + private float m_Timeout; + private EventHandler m_DownloadStartEventHandler; + private EventHandler m_DownloadUpdateEventHandler; + private EventHandler m_DownloadSuccessEventHandler; + private EventHandler m_DownloadFailureEventHandler; + + /// + /// 初始化下载管理器的新实例。 + /// + public DownloadManager() + { + m_TaskPool = new TaskPool(); + m_DownloadCounter = new DownloadCounter(1f, 10f); + m_FlushSize = OneMegaBytes; + m_Timeout = 30f; + m_DownloadStartEventHandler = null; + m_DownloadUpdateEventHandler = null; + m_DownloadSuccessEventHandler = null; + m_DownloadFailureEventHandler = null; + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return 5; + } + } + + /// + /// 获取或设置下载是否被暂停。 + /// + public bool Paused + { + get + { + return m_TaskPool.Paused; + } + set + { + m_TaskPool.Paused = value; + } + } + + /// + /// 获取下载代理总数量。 + /// + public int TotalAgentCount + { + get + { + return m_TaskPool.TotalAgentCount; + } + } + + /// + /// 获取可用下载代理数量。 + /// + public int FreeAgentCount + { + get + { + return m_TaskPool.FreeAgentCount; + } + } + + /// + /// 获取工作中下载代理数量。 + /// + public int WorkingAgentCount + { + get + { + return m_TaskPool.WorkingAgentCount; + } + } + + /// + /// 获取等待下载任务数量。 + /// + public int WaitingTaskCount + { + get + { + return m_TaskPool.WaitingTaskCount; + } + } + + /// + /// 获取或设置将缓冲区写入磁盘的临界大小。 + /// + public int FlushSize + { + get + { + return m_FlushSize; + } + set + { + m_FlushSize = value; + } + } + + /// + /// 获取或设置下载超时时长,以秒为单位。 + /// + public float Timeout + { + get + { + return m_Timeout; + } + set + { + m_Timeout = value; + } + } + + /// + /// 获取当前下载速度。 + /// + public float CurrentSpeed + { + get + { + return m_DownloadCounter.CurrentSpeed; + } + } + + /// + /// 下载开始事件。 + /// + public event EventHandler DownloadStart + { + add + { + m_DownloadStartEventHandler += value; + } + remove + { + m_DownloadStartEventHandler -= value; + } + } + + /// + /// 下载更新事件。 + /// + public event EventHandler DownloadUpdate + { + add + { + m_DownloadUpdateEventHandler += value; + } + remove + { + m_DownloadUpdateEventHandler -= value; + } + } + + /// + /// 下载成功事件。 + /// + public event EventHandler DownloadSuccess + { + add + { + m_DownloadSuccessEventHandler += value; + } + remove + { + m_DownloadSuccessEventHandler -= value; + } + } + + /// + /// 下载失败事件。 + /// + public event EventHandler DownloadFailure + { + add + { + m_DownloadFailureEventHandler += value; + } + remove + { + m_DownloadFailureEventHandler -= value; + } + } + + /// + /// 下载管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + m_TaskPool.Update(elapseSeconds, realElapseSeconds); + m_DownloadCounter.Update(elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理下载管理器。 + /// + internal override void Shutdown() + { + m_TaskPool.Shutdown(); + m_DownloadCounter.Shutdown(); + } + + /// + /// 增加下载代理辅助器。 + /// + /// 要增加的下载代理辅助器。 + public void AddDownloadAgentHelper(IDownloadAgentHelper downloadAgentHelper) + { + DownloadAgent agent = new DownloadAgent(downloadAgentHelper); + agent.DownloadAgentStart += OnDownloadAgentStart; + agent.DownloadAgentUpdate += OnDownloadAgentUpdate; + agent.DownloadAgentSuccess += OnDownloadAgentSuccess; + agent.DownloadAgentFailure += OnDownloadAgentFailure; + + m_TaskPool.AddAgent(agent); + } + + /// + /// 根据下载任务的序列编号获取下载任务的信息。 + /// + /// 要获取信息的下载任务的序列编号。 + /// 下载任务的信息。 + public TaskInfo GetDownloadInfo(int serialId) + { + return m_TaskPool.GetTaskInfo(serialId); + } + + /// + /// 根据下载任务的标签获取下载任务的信息。 + /// + /// 要获取信息的下载任务的标签。 + /// 下载任务的信息。 + public TaskInfo[] GetDownloadInfos(string tag) + { + return m_TaskPool.GetTaskInfos(tag); + } + + /// + /// 根据下载任务的标签获取下载任务的信息。 + /// + /// 要获取信息的下载任务的标签。 + /// 下载任务的信息。 + public void GetDownloadInfos(string tag, List results) + { + m_TaskPool.GetTaskInfos(tag, results); + } + + /// + /// 获取所有下载任务的信息。 + /// + /// 所有下载任务的信息。 + public TaskInfo[] GetAllDownloadInfos() + { + return m_TaskPool.GetAllTaskInfos(); + } + + /// + /// 获取所有下载任务的信息。 + /// + /// 所有下载任务的信息。 + public void GetAllDownloadInfos(List results) + { + m_TaskPool.GetAllTaskInfos(results); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri) + { + return AddDownload(downloadPath, downloadUri, null, Constant.DefaultPriority, null); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, string tag) + { + return AddDownload(downloadPath, downloadUri, tag, Constant.DefaultPriority, null); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的优先级。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, int priority) + { + return AddDownload(downloadPath, downloadUri, null, priority, null); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, object userData) + { + return AddDownload(downloadPath, downloadUri, null, Constant.DefaultPriority, userData); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 下载任务的优先级。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, string tag, int priority) + { + return AddDownload(downloadPath, downloadUri, tag, priority, null); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, string tag, object userData) + { + return AddDownload(downloadPath, downloadUri, tag, Constant.DefaultPriority, userData); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的优先级。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, int priority, object userData) + { + return AddDownload(downloadPath, downloadUri, null, priority, userData); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 下载任务的优先级。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, string tag, int priority, object userData) + { + if (string.IsNullOrEmpty(downloadPath)) + { + throw new GameFrameworkException("Download path is invalid."); + } + + if (string.IsNullOrEmpty(downloadUri)) + { + throw new GameFrameworkException("Download uri is invalid."); + } + + if (TotalAgentCount <= 0) + { + throw new GameFrameworkException("You must add download agent first."); + } + + DownloadTask downloadTask = DownloadTask.Create(downloadPath, downloadUri, tag, priority, m_FlushSize, m_Timeout, userData); + m_TaskPool.AddTask(downloadTask); + return downloadTask.SerialId; + } + + /// + /// 根据下载任务的序列编号移除下载任务。 + /// + /// 要移除下载任务的序列编号。 + /// 是否移除下载任务成功。 + public bool RemoveDownload(int serialId) + { + return m_TaskPool.RemoveTask(serialId); + } + + /// + /// 根据下载任务的标签移除下载任务。 + /// + /// 要移除下载任务的标签。 + /// 移除下载任务的数量。 + public int RemoveDownloads(string tag) + { + return m_TaskPool.RemoveTasks(tag); + } + + /// + /// 移除所有下载任务。 + /// + /// 移除下载任务的数量。 + public int RemoveAllDownloads() + { + return m_TaskPool.RemoveAllTasks(); + } + + private void OnDownloadAgentStart(DownloadAgent sender) + { + if (m_DownloadStartEventHandler != null) + { + DownloadStartEventArgs downloadStartEventArgs = DownloadStartEventArgs.Create(sender.Task.SerialId, sender.Task.DownloadPath, sender.Task.DownloadUri, sender.CurrentLength, sender.Task.UserData); + m_DownloadStartEventHandler(this, downloadStartEventArgs); + ReferencePool.Release(downloadStartEventArgs); + } + } + + private void OnDownloadAgentUpdate(DownloadAgent sender, int deltaLength) + { + m_DownloadCounter.RecordDeltaLength(deltaLength); + if (m_DownloadUpdateEventHandler != null) + { + DownloadUpdateEventArgs downloadUpdateEventArgs = DownloadUpdateEventArgs.Create(sender.Task.SerialId, sender.Task.DownloadPath, sender.Task.DownloadUri, sender.CurrentLength, sender.Task.UserData); + m_DownloadUpdateEventHandler(this, downloadUpdateEventArgs); + ReferencePool.Release(downloadUpdateEventArgs); + } + } + + private void OnDownloadAgentSuccess(DownloadAgent sender, long length) + { + if (m_DownloadSuccessEventHandler != null) + { + DownloadSuccessEventArgs downloadSuccessEventArgs = DownloadSuccessEventArgs.Create(sender.Task.SerialId, sender.Task.DownloadPath, sender.Task.DownloadUri, sender.CurrentLength, sender.Task.UserData); + m_DownloadSuccessEventHandler(this, downloadSuccessEventArgs); + ReferencePool.Release(downloadSuccessEventArgs); + } + } + + private void OnDownloadAgentFailure(DownloadAgent sender, string errorMessage) + { + if (m_DownloadFailureEventHandler != null) + { + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(sender.Task.SerialId, sender.Task.DownloadPath, sender.Task.DownloadUri, errorMessage, sender.Task.UserData); + m_DownloadFailureEventHandler(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.cs.meta new file mode 100644 index 0000000..dc038a1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 729fb53ec60059a40a020bea77ab2c74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadStartEventArgs.cs new file mode 100644 index 0000000..7f7c826 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadStartEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载开始事件。 + /// + public sealed class DownloadStartEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化下载开始事件的新实例。 + /// + public DownloadStartEventArgs() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + + /// + /// 获取下载任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前大小。 + /// + public long CurrentLength + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建下载开始事件。 + /// + /// 下载任务的序列编号。 + /// 下载后存放路径。 + /// 下载地址。 + /// 当前大小。 + /// 用户自定义数据。 + /// 创建的下载开始事件。 + public static DownloadStartEventArgs Create(int serialId, string downloadPath, string downloadUri, long currentLength, object userData) + { + DownloadStartEventArgs downloadStartEventArgs = ReferencePool.Acquire(); + downloadStartEventArgs.SerialId = serialId; + downloadStartEventArgs.DownloadPath = downloadPath; + downloadStartEventArgs.DownloadUri = downloadUri; + downloadStartEventArgs.CurrentLength = currentLength; + downloadStartEventArgs.UserData = userData; + return downloadStartEventArgs; + } + + /// + /// 清理下载开始事件。 + /// + public override void Clear() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadStartEventArgs.cs.meta new file mode 100644 index 0000000..f8bbe1f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2974e6322549924e9278b93d1e1fd13 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadSuccessEventArgs.cs new file mode 100644 index 0000000..57be62d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadSuccessEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载成功事件。 + /// + public sealed class DownloadSuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化下载成功事件的新实例。 + /// + public DownloadSuccessEventArgs() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + + /// + /// 获取下载任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前大小。 + /// + public long CurrentLength + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建下载成功事件。 + /// + /// 下载任务的序列编号。 + /// 下载后存放路径。 + /// 下载地址。 + /// 当前大小。 + /// 用户自定义数据。 + /// 创建的下载成功事件。 + public static DownloadSuccessEventArgs Create(int serialId, string downloadPath, string downloadUri, long currentLength, object userData) + { + DownloadSuccessEventArgs downloadSuccessEventArgs = ReferencePool.Acquire(); + downloadSuccessEventArgs.SerialId = serialId; + downloadSuccessEventArgs.DownloadPath = downloadPath; + downloadSuccessEventArgs.DownloadUri = downloadUri; + downloadSuccessEventArgs.CurrentLength = currentLength; + downloadSuccessEventArgs.UserData = userData; + return downloadSuccessEventArgs; + } + + /// + /// 清理下载成功事件。 + /// + public override void Clear() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadSuccessEventArgs.cs.meta new file mode 100644 index 0000000..0366245 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d225adc5f17c97a42b5da79324b975a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadUpdateEventArgs.cs new file mode 100644 index 0000000..8741695 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadUpdateEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Download +{ + /// + /// 下载更新事件。 + /// + public sealed class DownloadUpdateEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化下载更新事件的新实例。 + /// + public DownloadUpdateEventArgs() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + + /// + /// 获取下载任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前大小。 + /// + public long CurrentLength + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建下载更新事件。 + /// + /// 下载任务的序列编号。 + /// 下载后存放路径。 + /// 下载地址。 + /// 当前大小。 + /// 用户自定义数据。 + /// 创建的下载更新事件。 + public static DownloadUpdateEventArgs Create(int serialId, string downloadPath, string downloadUri, long currentLength, object userData) + { + DownloadUpdateEventArgs downloadUpdateEventArgs = ReferencePool.Acquire(); + downloadUpdateEventArgs.SerialId = serialId; + downloadUpdateEventArgs.DownloadPath = downloadPath; + downloadUpdateEventArgs.DownloadUri = downloadUri; + downloadUpdateEventArgs.CurrentLength = currentLength; + downloadUpdateEventArgs.UserData = userData; + return downloadUpdateEventArgs; + } + + /// + /// 清理下载更新事件。 + /// + public override void Clear() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadUpdateEventArgs.cs.meta new file mode 100644 index 0000000..bbb25de --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/DownloadUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d7640e13d60d34449a048583aa00936 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadAgentHelper.cs new file mode 100644 index 0000000..14757e6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadAgentHelper.cs @@ -0,0 +1,66 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.Download +{ + /// + /// 下载代理辅助器接口。 + /// + public interface IDownloadAgentHelper + { + /// + /// 下载代理辅助器更新数据流事件。 + /// + event EventHandler DownloadAgentHelperUpdateBytes; + + /// + /// 下载代理辅助器更新数据大小事件。 + /// + event EventHandler DownloadAgentHelperUpdateLength; + + /// + /// 下载代理辅助器完成事件。 + /// + event EventHandler DownloadAgentHelperComplete; + + /// + /// 下载代理辅助器错误事件。 + /// + event EventHandler DownloadAgentHelperError; + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 用户自定义数据。 + void Download(string downloadUri, object userData); + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 下载数据起始位置。 + /// 用户自定义数据。 + void Download(string downloadUri, long fromPosition, object userData); + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 下载数据起始位置。 + /// 下载数据结束位置。 + /// 用户自定义数据。 + void Download(string downloadUri, long fromPosition, long toPosition, object userData); + + /// + /// 重置下载代理辅助器。 + /// + void Reset(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadAgentHelper.cs.meta new file mode 100644 index 0000000..ab9fda6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f96087ef0c8ca5f49813ac4166698485 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadManager.cs new file mode 100644 index 0000000..ffe352f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadManager.cs @@ -0,0 +1,240 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Download +{ + /// + /// 下载管理器接口。 + /// + public interface IDownloadManager + { + /// + /// 获取或设置下载是否被暂停。 + /// + bool Paused + { + get; + set; + } + + /// + /// 获取下载代理总数量。 + /// + int TotalAgentCount + { + get; + } + + /// + /// 获取可用下载代理数量。 + /// + int FreeAgentCount + { + get; + } + + /// + /// 获取工作中下载代理数量。 + /// + int WorkingAgentCount + { + get; + } + + /// + /// 获取等待下载任务数量。 + /// + int WaitingTaskCount + { + get; + } + + /// + /// 获取或设置将缓冲区写入磁盘的临界大小。 + /// + int FlushSize + { + get; + set; + } + + /// + /// 获取或设置下载超时时长,以秒为单位。 + /// + float Timeout + { + get; + set; + } + + /// + /// 获取当前下载速度。 + /// + float CurrentSpeed + { + get; + } + + /// + /// 下载开始事件。 + /// + event EventHandler DownloadStart; + + /// + /// 下载更新事件。 + /// + event EventHandler DownloadUpdate; + + /// + /// 下载成功事件。 + /// + event EventHandler DownloadSuccess; + + /// + /// 下载失败事件。 + /// + event EventHandler DownloadFailure; + + /// + /// 增加下载代理辅助器。 + /// + /// 要增加的下载代理辅助器。 + void AddDownloadAgentHelper(IDownloadAgentHelper downloadAgentHelper); + + /// + /// 根据下载任务的序列编号获取下载任务的信息。 + /// + /// 要获取信息的下载任务的序列编号。 + /// 下载任务的信息。 + TaskInfo GetDownloadInfo(int serialId); + + /// + /// 根据下载任务的标签获取下载任务的信息。 + /// + /// 要获取信息的下载任务的标签。 + /// 下载任务的信息。 + TaskInfo[] GetDownloadInfos(string tag); + + /// + /// 根据下载任务的标签获取下载任务的信息。 + /// + /// 要获取信息的下载任务的标签。 + /// 下载任务的信息。 + void GetDownloadInfos(string tag, List results); + + /// + /// 获取所有下载任务的信息。 + /// + /// 所有下载任务的信息。 + TaskInfo[] GetAllDownloadInfos(); + + /// + /// 获取所有下载任务的信息。 + /// + /// 所有下载任务的信息。 + void GetAllDownloadInfos(List results); + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 新增下载任务的序列编号。 + int AddDownload(string downloadPath, string downloadUri); + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 新增下载任务的序列编号。 + int AddDownload(string downloadPath, string downloadUri, string tag); + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的优先级。 + /// 新增下载任务的序列编号。 + int AddDownload(string downloadPath, string downloadUri, int priority); + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + int AddDownload(string downloadPath, string downloadUri, object userData); + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 下载任务的优先级。 + /// 新增下载任务的序列编号。 + int AddDownload(string downloadPath, string downloadUri, string tag, int priority); + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + int AddDownload(string downloadPath, string downloadUri, string tag, object userData); + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的优先级。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + int AddDownload(string downloadPath, string downloadUri, int priority, object userData); + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 下载任务的优先级。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + int AddDownload(string downloadPath, string downloadUri, string tag, int priority, object userData); + + /// + /// 根据下载任务的序列编号移除下载任务。 + /// + /// 要移除下载任务的序列编号。 + /// 是否移除下载任务成功。 + bool RemoveDownload(int serialId); + + /// + /// 根据下载任务的标签移除下载任务。 + /// + /// 要移除下载任务的标签。 + /// 移除下载任务的数量。 + int RemoveDownloads(string tag); + + /// + /// 移除所有下载任务。 + /// + /// 移除下载任务的数量。 + int RemoveAllDownloads(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadManager.cs.meta new file mode 100644 index 0000000..b9a5b04 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Download/IDownloadManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc56bc96a4239f849b19f8aaf8b694ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity.meta new file mode 100644 index 0000000..e9ddc57 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 180218d2dcfcc66418af572848317bfd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityGroup.cs new file mode 100644 index 0000000..68d340a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityGroup.cs @@ -0,0 +1,394 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; +using System.Collections.Generic; + +namespace GameFramework.Entity +{ + internal sealed partial class EntityManager : GameFrameworkModule, IEntityManager + { + /// + /// 实体组。 + /// + private sealed class EntityGroup : IEntityGroup + { + private readonly string m_Name; + private readonly IEntityGroupHelper m_EntityGroupHelper; + private readonly IObjectPool m_InstancePool; + private readonly GameFrameworkLinkedList m_Entities; + private LinkedListNode m_CachedNode; + + /// + /// 初始化实体组的新实例。 + /// + /// 实体组名称。 + /// 实体实例对象池自动释放可释放对象的间隔秒数。 + /// 实体实例对象池容量。 + /// 实体实例对象池对象过期秒数。 + /// 实体实例对象池的优先级。 + /// 实体组辅助器。 + /// 对象池管理器。 + public EntityGroup(string name, float instanceAutoReleaseInterval, int instanceCapacity, float instanceExpireTime, int instancePriority, IEntityGroupHelper entityGroupHelper, IObjectPoolManager objectPoolManager) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Entity group name is invalid."); + } + + if (entityGroupHelper == null) + { + throw new GameFrameworkException("Entity group helper is invalid."); + } + + m_Name = name; + m_EntityGroupHelper = entityGroupHelper; + m_InstancePool = objectPoolManager.CreateSingleSpawnObjectPool(Utility.Text.Format("Entity Instance Pool ({0})", name), instanceCapacity, instanceExpireTime, instancePriority); + m_InstancePool.AutoReleaseInterval = instanceAutoReleaseInterval; + m_Entities = new GameFrameworkLinkedList(); + m_CachedNode = null; + } + + /// + /// 获取实体组名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取实体组中实体数量。 + /// + public int EntityCount + { + get + { + return m_Entities.Count; + } + } + + /// + /// 获取或设置实体组实例对象池自动释放可释放对象的间隔秒数。 + /// + public float InstanceAutoReleaseInterval + { + get + { + return m_InstancePool.AutoReleaseInterval; + } + set + { + m_InstancePool.AutoReleaseInterval = value; + } + } + + /// + /// 获取或设置实体组实例对象池的容量。 + /// + public int InstanceCapacity + { + get + { + return m_InstancePool.Capacity; + } + set + { + m_InstancePool.Capacity = value; + } + } + + /// + /// 获取或设置实体组实例对象池对象过期秒数。 + /// + public float InstanceExpireTime + { + get + { + return m_InstancePool.ExpireTime; + } + set + { + m_InstancePool.ExpireTime = value; + } + } + + /// + /// 获取或设置实体组实例对象池的优先级。 + /// + public int InstancePriority + { + get + { + return m_InstancePool.Priority; + } + set + { + m_InstancePool.Priority = value; + } + } + + /// + /// 获取实体组辅助器。 + /// + public IEntityGroupHelper Helper + { + get + { + return m_EntityGroupHelper; + } + } + + /// + /// 实体组轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + LinkedListNode current = m_Entities.First; + while (current != null) + { + m_CachedNode = current.Next; + current.Value.OnUpdate(elapseSeconds, realElapseSeconds); + current = m_CachedNode; + m_CachedNode = null; + } + } + + /// + /// 实体组中是否存在实体。 + /// + /// 实体序列编号。 + /// 实体组中是否存在实体。 + public bool HasEntity(int entityId) + { + foreach (IEntity entity in m_Entities) + { + if (entity.Id == entityId) + { + return true; + } + } + + return false; + } + + /// + /// 实体组中是否存在实体。 + /// + /// 实体资源名称。 + /// 实体组中是否存在实体。 + public bool HasEntity(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + foreach (IEntity entity in m_Entities) + { + if (entity.EntityAssetName == entityAssetName) + { + return true; + } + } + + return false; + } + + /// + /// 从实体组中获取实体。 + /// + /// 实体序列编号。 + /// 要获取的实体。 + public IEntity GetEntity(int entityId) + { + foreach (IEntity entity in m_Entities) + { + if (entity.Id == entityId) + { + return entity; + } + } + + return null; + } + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public IEntity GetEntity(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + foreach (IEntity entity in m_Entities) + { + if (entity.EntityAssetName == entityAssetName) + { + return entity; + } + } + + return null; + } + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public IEntity[] GetEntities(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + List results = new List(); + foreach (IEntity entity in m_Entities) + { + if (entity.EntityAssetName == entityAssetName) + { + results.Add(entity); + } + } + + return results.ToArray(); + } + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public void GetEntities(string entityAssetName, List results) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (IEntity entity in m_Entities) + { + if (entity.EntityAssetName == entityAssetName) + { + results.Add(entity); + } + } + } + + /// + /// 从实体组中获取所有实体。 + /// + /// 实体组中的所有实体。 + public IEntity[] GetAllEntities() + { + List results = new List(); + foreach (IEntity entity in m_Entities) + { + results.Add(entity); + } + + return results.ToArray(); + } + + /// + /// 从实体组中获取所有实体。 + /// + /// 实体组中的所有实体。 + public void GetAllEntities(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (IEntity entity in m_Entities) + { + results.Add(entity); + } + } + + /// + /// 往实体组增加实体。 + /// + /// 要增加的实体。 + public void AddEntity(IEntity entity) + { + m_Entities.AddLast(entity); + } + + /// + /// 从实体组移除实体。 + /// + /// 要移除的实体。 + public void RemoveEntity(IEntity entity) + { + if (m_CachedNode != null && m_CachedNode.Value == entity) + { + m_CachedNode = m_CachedNode.Next; + } + + if (!m_Entities.Remove(entity)) + { + throw new GameFrameworkException(Utility.Text.Format("Entity group '{0}' not exists specified entity '[{1}]{2}'.", m_Name, entity.Id, entity.EntityAssetName)); + } + } + + public void RegisterEntityInstanceObject(EntityInstanceObject obj, bool spawned) + { + m_InstancePool.Register(obj, spawned); + } + + public EntityInstanceObject SpawnEntityInstanceObject(string name) + { + return m_InstancePool.Spawn(name); + } + + public void UnspawnEntity(IEntity entity) + { + m_InstancePool.Unspawn(entity.Handle); + } + + public void SetEntityInstanceLocked(object entityInstance, bool locked) + { + if (entityInstance == null) + { + throw new GameFrameworkException("Entity instance is invalid."); + } + + m_InstancePool.SetLocked(entityInstance, locked); + } + + public void SetEntityInstancePriority(object entityInstance, int priority) + { + if (entityInstance == null) + { + throw new GameFrameworkException("Entity instance is invalid."); + } + + m_InstancePool.SetPriority(entityInstance, priority); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityGroup.cs.meta new file mode 100644 index 0000000..a1e47ad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05a88a175c90f86408faa1ed513f632a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInfo.cs new file mode 100644 index 0000000..f9b4c63 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInfo.cs @@ -0,0 +1,136 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Entity +{ + internal sealed partial class EntityManager : GameFrameworkModule, IEntityManager + { + /// + /// 实体信息。 + /// + private sealed class EntityInfo : IReference + { + private IEntity m_Entity; + private EntityStatus m_Status; + private IEntity m_ParentEntity; + private List m_ChildEntities; + + public EntityInfo() + { + m_Entity = null; + m_Status = EntityStatus.Unknown; + m_ParentEntity = null; + m_ChildEntities = new List(); + } + + public IEntity Entity + { + get + { + return m_Entity; + } + } + + public EntityStatus Status + { + get + { + return m_Status; + } + set + { + m_Status = value; + } + } + + public IEntity ParentEntity + { + get + { + return m_ParentEntity; + } + set + { + m_ParentEntity = value; + } + } + + public int ChildEntityCount + { + get + { + return m_ChildEntities.Count; + } + } + + public static EntityInfo Create(IEntity entity) + { + if (entity == null) + { + throw new GameFrameworkException("Entity is invalid."); + } + + EntityInfo entityInfo = ReferencePool.Acquire(); + entityInfo.m_Entity = entity; + entityInfo.m_Status = EntityStatus.WillInit; + return entityInfo; + } + + public void Clear() + { + m_Entity = null; + m_Status = EntityStatus.Unknown; + m_ParentEntity = null; + m_ChildEntities.Clear(); + } + + public IEntity GetChildEntity() + { + return m_ChildEntities.Count > 0 ? m_ChildEntities[0] : null; + } + + public IEntity[] GetChildEntities() + { + return m_ChildEntities.ToArray(); + } + + public void GetChildEntities(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (IEntity childEntity in m_ChildEntities) + { + results.Add(childEntity); + } + } + + public void AddChildEntity(IEntity childEntity) + { + if (m_ChildEntities.Contains(childEntity)) + { + throw new GameFrameworkException("Can not add child entity which is already exist."); + } + + m_ChildEntities.Add(childEntity); + } + + public void RemoveChildEntity(IEntity childEntity) + { + if (!m_ChildEntities.Remove(childEntity)) + { + throw new GameFrameworkException("Can not remove child entity which is not exist."); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInfo.cs.meta new file mode 100644 index 0000000..683c5f0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c9d5a756ddb574419edab3f3f9eb4e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInstanceObject.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInstanceObject.cs new file mode 100644 index 0000000..ec9af19 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInstanceObject.cs @@ -0,0 +1,60 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; + +namespace GameFramework.Entity +{ + internal sealed partial class EntityManager : GameFrameworkModule, IEntityManager + { + /// + /// 实体实例对象。 + /// + private sealed class EntityInstanceObject : ObjectBase + { + private object m_EntityAsset; + private IEntityHelper m_EntityHelper; + + public EntityInstanceObject() + { + m_EntityAsset = null; + m_EntityHelper = null; + } + + public static EntityInstanceObject Create(string name, object entityAsset, object entityInstance, IEntityHelper entityHelper) + { + if (entityAsset == null) + { + throw new GameFrameworkException("Entity asset is invalid."); + } + + if (entityHelper == null) + { + throw new GameFrameworkException("Entity helper is invalid."); + } + + EntityInstanceObject entityInstanceObject = ReferencePool.Acquire(); + entityInstanceObject.Initialize(name, entityInstance); + entityInstanceObject.m_EntityAsset = entityAsset; + entityInstanceObject.m_EntityHelper = entityHelper; + return entityInstanceObject; + } + + public override void Clear() + { + base.Clear(); + m_EntityAsset = null; + m_EntityHelper = null; + } + + protected internal override void Release(bool isShutdown) + { + m_EntityHelper.ReleaseEntity(m_EntityAsset, Target); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInstanceObject.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInstanceObject.cs.meta new file mode 100644 index 0000000..8bf221c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityInstanceObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 78dfd3faf2fe0d348ba7c22d745702be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityStatus.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityStatus.cs new file mode 100644 index 0000000..3bfdc4c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityStatus.cs @@ -0,0 +1,28 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + internal sealed partial class EntityManager : GameFrameworkModule, IEntityManager + { + /// + /// 实体状态。 + /// + private enum EntityStatus : byte + { + Unknown = 0, + WillInit, + Inited, + WillShow, + Showed, + WillHide, + Hidden, + WillRecycle, + Recycled + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityStatus.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityStatus.cs.meta new file mode 100644 index 0000000..15dfacb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.EntityStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: adc7d533633489d439b2e8542edac1f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.ShowEntityInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.ShowEntityInfo.cs new file mode 100644 index 0000000..c395063 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.ShowEntityInfo.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + internal sealed partial class EntityManager : GameFrameworkModule, IEntityManager + { + private sealed class ShowEntityInfo : IReference + { + private int m_SerialId; + private int m_EntityId; + private EntityGroup m_EntityGroup; + private object m_UserData; + + public ShowEntityInfo() + { + m_SerialId = 0; + m_EntityId = 0; + m_EntityGroup = null; + m_UserData = null; + } + + public int SerialId + { + get + { + return m_SerialId; + } + } + + public int EntityId + { + get + { + return m_EntityId; + } + } + + public EntityGroup EntityGroup + { + get + { + return m_EntityGroup; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + + public static ShowEntityInfo Create(int serialId, int entityId, EntityGroup entityGroup, object userData) + { + ShowEntityInfo showEntityInfo = ReferencePool.Acquire(); + showEntityInfo.m_SerialId = serialId; + showEntityInfo.m_EntityId = entityId; + showEntityInfo.m_EntityGroup = entityGroup; + showEntityInfo.m_UserData = userData; + return showEntityInfo; + } + + public void Clear() + { + m_SerialId = 0; + m_EntityId = 0; + m_EntityGroup = null; + m_UserData = null; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.ShowEntityInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.ShowEntityInfo.cs.meta new file mode 100644 index 0000000..5ea6bc5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.ShowEntityInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc8fd464aae90174b94b8992940f604a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.cs new file mode 100644 index 0000000..33188e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.cs @@ -0,0 +1,1327 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.Entity +{ + /// + /// 实体管理器。 + /// + internal sealed partial class EntityManager : GameFrameworkModule, IEntityManager + { + private readonly Dictionary m_EntityInfos; + private readonly Dictionary m_EntityGroups; + private readonly Dictionary m_EntitiesBeingLoaded; + private readonly HashSet m_EntitiesToReleaseOnLoad; + private readonly Queue m_RecycleQueue; + private readonly LoadAssetCallbacks m_LoadAssetCallbacks; + private IObjectPoolManager m_ObjectPoolManager; + private IResourceManager m_ResourceManager; + private IEntityHelper m_EntityHelper; + private int m_Serial; + private bool m_IsShutdown; + private EventHandler m_ShowEntitySuccessEventHandler; + private EventHandler m_ShowEntityFailureEventHandler; + private EventHandler m_ShowEntityUpdateEventHandler; + private EventHandler m_ShowEntityDependencyAssetEventHandler; + private EventHandler m_HideEntityCompleteEventHandler; + + /// + /// 初始化实体管理器的新实例。 + /// + public EntityManager() + { + m_EntityInfos = new Dictionary(); + m_EntityGroups = new Dictionary(StringComparer.Ordinal); + m_EntitiesBeingLoaded = new Dictionary(); + m_EntitiesToReleaseOnLoad = new HashSet(); + m_RecycleQueue = new Queue(); + m_LoadAssetCallbacks = new LoadAssetCallbacks(LoadAssetSuccessCallback, LoadAssetFailureCallback, LoadAssetUpdateCallback, LoadAssetDependencyAssetCallback); + m_ObjectPoolManager = null; + m_ResourceManager = null; + m_EntityHelper = null; + m_Serial = 0; + m_IsShutdown = false; + m_ShowEntitySuccessEventHandler = null; + m_ShowEntityFailureEventHandler = null; + m_ShowEntityUpdateEventHandler = null; + m_ShowEntityDependencyAssetEventHandler = null; + m_HideEntityCompleteEventHandler = null; + } + + /// + /// 获取实体数量。 + /// + public int EntityCount + { + get + { + return m_EntityInfos.Count; + } + } + + /// + /// 获取实体组数量。 + /// + public int EntityGroupCount + { + get + { + return m_EntityGroups.Count; + } + } + + /// + /// 显示实体成功事件。 + /// + public event EventHandler ShowEntitySuccess + { + add + { + m_ShowEntitySuccessEventHandler += value; + } + remove + { + m_ShowEntitySuccessEventHandler -= value; + } + } + + /// + /// 显示实体失败事件。 + /// + public event EventHandler ShowEntityFailure + { + add + { + m_ShowEntityFailureEventHandler += value; + } + remove + { + m_ShowEntityFailureEventHandler -= value; + } + } + + /// + /// 显示实体更新事件。 + /// + public event EventHandler ShowEntityUpdate + { + add + { + m_ShowEntityUpdateEventHandler += value; + } + remove + { + m_ShowEntityUpdateEventHandler -= value; + } + } + + /// + /// 显示实体时加载依赖资源事件。 + /// + public event EventHandler ShowEntityDependencyAsset + { + add + { + m_ShowEntityDependencyAssetEventHandler += value; + } + remove + { + m_ShowEntityDependencyAssetEventHandler -= value; + } + } + + /// + /// 隐藏实体完成事件。 + /// + public event EventHandler HideEntityComplete + { + add + { + m_HideEntityCompleteEventHandler += value; + } + remove + { + m_HideEntityCompleteEventHandler -= value; + } + } + + /// + /// 实体管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + while (m_RecycleQueue.Count > 0) + { + EntityInfo entityInfo = m_RecycleQueue.Dequeue(); + IEntity entity = entityInfo.Entity; + EntityGroup entityGroup = (EntityGroup)entity.EntityGroup; + if (entityGroup == null) + { + throw new GameFrameworkException("Entity group is invalid."); + } + + entityInfo.Status = EntityStatus.WillRecycle; + entity.OnRecycle(); + entityInfo.Status = EntityStatus.Recycled; + entityGroup.UnspawnEntity(entity); + ReferencePool.Release(entityInfo); + } + + foreach (KeyValuePair entityGroup in m_EntityGroups) + { + entityGroup.Value.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理实体管理器。 + /// + internal override void Shutdown() + { + m_IsShutdown = true; + HideAllLoadedEntities(); + m_EntityGroups.Clear(); + m_EntitiesBeingLoaded.Clear(); + m_EntitiesToReleaseOnLoad.Clear(); + m_RecycleQueue.Clear(); + } + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + public void SetObjectPoolManager(IObjectPoolManager objectPoolManager) + { + if (objectPoolManager == null) + { + throw new GameFrameworkException("Object pool manager is invalid."); + } + + m_ObjectPoolManager = objectPoolManager; + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + public void SetResourceManager(IResourceManager resourceManager) + { + if (resourceManager == null) + { + throw new GameFrameworkException("Resource manager is invalid."); + } + + m_ResourceManager = resourceManager; + } + + /// + /// 设置实体辅助器。 + /// + /// 实体辅助器。 + public void SetEntityHelper(IEntityHelper entityHelper) + { + if (entityHelper == null) + { + throw new GameFrameworkException("Entity helper is invalid."); + } + + m_EntityHelper = entityHelper; + } + + /// + /// 是否存在实体组。 + /// + /// 实体组名称。 + /// 是否存在实体组。 + public bool HasEntityGroup(string entityGroupName) + { + if (string.IsNullOrEmpty(entityGroupName)) + { + throw new GameFrameworkException("Entity group name is invalid."); + } + + return m_EntityGroups.ContainsKey(entityGroupName); + } + + /// + /// 获取实体组。 + /// + /// 实体组名称。 + /// 要获取的实体组。 + public IEntityGroup GetEntityGroup(string entityGroupName) + { + if (string.IsNullOrEmpty(entityGroupName)) + { + throw new GameFrameworkException("Entity group name is invalid."); + } + + EntityGroup entityGroup = null; + if (m_EntityGroups.TryGetValue(entityGroupName, out entityGroup)) + { + return entityGroup; + } + + return null; + } + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + public IEntityGroup[] GetAllEntityGroups() + { + int index = 0; + IEntityGroup[] results = new IEntityGroup[m_EntityGroups.Count]; + foreach (KeyValuePair entityGroup in m_EntityGroups) + { + results[index++] = entityGroup.Value; + } + + return results; + } + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + public void GetAllEntityGroups(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair entityGroup in m_EntityGroups) + { + results.Add(entityGroup.Value); + } + } + + /// + /// 增加实体组。 + /// + /// 实体组名称。 + /// 实体实例对象池自动释放可释放对象的间隔秒数。 + /// 实体实例对象池容量。 + /// 实体实例对象池对象过期秒数。 + /// 实体实例对象池的优先级。 + /// 实体组辅助器。 + /// 是否增加实体组成功。 + public bool AddEntityGroup(string entityGroupName, float instanceAutoReleaseInterval, int instanceCapacity, float instanceExpireTime, int instancePriority, IEntityGroupHelper entityGroupHelper) + { + if (string.IsNullOrEmpty(entityGroupName)) + { + throw new GameFrameworkException("Entity group name is invalid."); + } + + if (entityGroupHelper == null) + { + throw new GameFrameworkException("Entity group helper is invalid."); + } + + if (m_ObjectPoolManager == null) + { + throw new GameFrameworkException("You must set object pool manager first."); + } + + if (HasEntityGroup(entityGroupName)) + { + return false; + } + + m_EntityGroups.Add(entityGroupName, new EntityGroup(entityGroupName, instanceAutoReleaseInterval, instanceCapacity, instanceExpireTime, instancePriority, entityGroupHelper, m_ObjectPoolManager)); + + return true; + } + + /// + /// 是否存在实体。 + /// + /// 实体编号。 + /// 是否存在实体。 + public bool HasEntity(int entityId) + { + return m_EntityInfos.ContainsKey(entityId); + } + + /// + /// 是否存在实体。 + /// + /// 实体资源名称。 + /// 是否存在实体。 + public bool HasEntity(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) + { + return true; + } + } + + return false; + } + + /// + /// 获取实体。 + /// + /// 实体编号。 + /// 要获取的实体。 + public IEntity GetEntity(int entityId) + { + EntityInfo entityInfo = GetEntityInfo(entityId); + if (entityInfo == null) + { + return null; + } + + return entityInfo.Entity; + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public IEntity GetEntity(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) + { + return entityInfo.Value.Entity; + } + } + + return null; + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public IEntity[] GetEntities(string entityAssetName) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + List results = new List(); + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) + { + results.Add(entityInfo.Value.Entity); + } + } + + return results.ToArray(); + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public void GetEntities(string entityAssetName, List results) + { + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + if (entityInfo.Value.Entity.EntityAssetName == entityAssetName) + { + results.Add(entityInfo.Value.Entity); + } + } + } + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + public IEntity[] GetAllLoadedEntities() + { + int index = 0; + IEntity[] results = new IEntity[m_EntityInfos.Count]; + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + results[index++] = entityInfo.Value.Entity; + } + + return results; + } + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + public void GetAllLoadedEntities(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + results.Add(entityInfo.Value.Entity); + } + } + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + public int[] GetAllLoadingEntityIds() + { + int index = 0; + int[] results = new int[m_EntitiesBeingLoaded.Count]; + foreach (KeyValuePair entityBeingLoaded in m_EntitiesBeingLoaded) + { + results[index++] = entityBeingLoaded.Key; + } + + return results; + } + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + public void GetAllLoadingEntityIds(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair entityBeingLoaded in m_EntitiesBeingLoaded) + { + results.Add(entityBeingLoaded.Key); + } + } + + /// + /// 是否正在加载实体。 + /// + /// 实体编号。 + /// 是否正在加载实体。 + public bool IsLoadingEntity(int entityId) + { + return m_EntitiesBeingLoaded.ContainsKey(entityId); + } + + /// + /// 是否是合法的实体。 + /// + /// 实体。 + /// 实体是否合法。 + public bool IsValidEntity(IEntity entity) + { + if (entity == null) + { + return false; + } + + return HasEntity(entity.Id); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName) + { + ShowEntity(entityId, entityAssetName, entityGroupName, Constant.DefaultPriority, null); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority) + { + ShowEntity(entityId, entityAssetName, entityGroupName, priority, null); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, object userData) + { + ShowEntity(entityId, entityAssetName, entityGroupName, Constant.DefaultPriority, userData); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority, object userData) + { + if (m_ResourceManager == null) + { + throw new GameFrameworkException("You must set resource manager first."); + } + + if (m_EntityHelper == null) + { + throw new GameFrameworkException("You must set entity helper first."); + } + + if (string.IsNullOrEmpty(entityAssetName)) + { + throw new GameFrameworkException("Entity asset name is invalid."); + } + + if (string.IsNullOrEmpty(entityGroupName)) + { + throw new GameFrameworkException("Entity group name is invalid."); + } + + if (HasEntity(entityId)) + { + throw new GameFrameworkException(Utility.Text.Format("Entity id '{0}' is already exist.", entityId)); + } + + if (IsLoadingEntity(entityId)) + { + throw new GameFrameworkException(Utility.Text.Format("Entity '{0}' is already being loaded.", entityId)); + } + + EntityGroup entityGroup = (EntityGroup)GetEntityGroup(entityGroupName); + if (entityGroup == null) + { + throw new GameFrameworkException(Utility.Text.Format("Entity group '{0}' is not exist.", entityGroupName)); + } + + EntityInstanceObject entityInstanceObject = entityGroup.SpawnEntityInstanceObject(entityAssetName); + if (entityInstanceObject == null) + { + int serialId = ++m_Serial; + m_EntitiesBeingLoaded.Add(entityId, serialId); + m_ResourceManager.LoadAsset(entityAssetName, priority, m_LoadAssetCallbacks, ShowEntityInfo.Create(serialId, entityId, entityGroup, userData)); + return; + } + + InternalShowEntity(entityId, entityAssetName, entityGroup, entityInstanceObject.Target, false, 0f, userData); + } + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + public void HideEntity(int entityId) + { + HideEntity(entityId, null); + } + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + /// 用户自定义数据。 + public void HideEntity(int entityId, object userData) + { + if (IsLoadingEntity(entityId)) + { + m_EntitiesToReleaseOnLoad.Add(m_EntitiesBeingLoaded[entityId]); + m_EntitiesBeingLoaded.Remove(entityId); + return; + } + + EntityInfo entityInfo = GetEntityInfo(entityId); + if (entityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find entity '{0}'.", entityId)); + } + + InternalHideEntity(entityInfo, userData); + } + + /// + /// 隐藏实体。 + /// + /// 实体。 + public void HideEntity(IEntity entity) + { + HideEntity(entity, null); + } + + /// + /// 隐藏实体。 + /// + /// 实体。 + /// 用户自定义数据。 + public void HideEntity(IEntity entity, object userData) + { + if (entity == null) + { + throw new GameFrameworkException("Entity is invalid."); + } + + HideEntity(entity.Id, userData); + } + + /// + /// 隐藏所有已加载的实体。 + /// + public void HideAllLoadedEntities() + { + HideAllLoadedEntities(null); + } + + /// + /// 隐藏所有已加载的实体。 + /// + /// 用户自定义数据。 + public void HideAllLoadedEntities(object userData) + { + while (m_EntityInfos.Count > 0) + { + foreach (KeyValuePair entityInfo in m_EntityInfos) + { + InternalHideEntity(entityInfo.Value, userData); + break; + } + } + } + + /// + /// 隐藏所有正在加载的实体。 + /// + public void HideAllLoadingEntities() + { + foreach (KeyValuePair entityBeingLoaded in m_EntitiesBeingLoaded) + { + m_EntitiesToReleaseOnLoad.Add(entityBeingLoaded.Value); + } + + m_EntitiesBeingLoaded.Clear(); + } + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体的实体编号。 + /// 子实体的父实体。 + public IEntity GetParentEntity(int childEntityId) + { + EntityInfo childEntityInfo = GetEntityInfo(childEntityId); + if (childEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find child entity '{0}'.", childEntityId)); + } + + return childEntityInfo.ParentEntity; + } + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体。 + /// 子实体的父实体。 + public IEntity GetParentEntity(IEntity childEntity) + { + if (childEntity == null) + { + throw new GameFrameworkException("Child entity is invalid."); + } + + return GetParentEntity(childEntity.Id); + } + + /// + /// 获取子实体数量。 + /// + /// 要获取子实体数量的父实体的实体编号。 + /// 子实体数量。 + public int GetChildEntityCount(int parentEntityId) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); + } + + return parentEntityInfo.ChildEntityCount; + } + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体的实体编号。 + /// 子实体。 + public IEntity GetChildEntity(int parentEntityId) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); + } + + return parentEntityInfo.GetChildEntity(); + } + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体。 + /// 子实体。 + public IEntity GetChildEntity(IEntity parentEntity) + { + if (parentEntity == null) + { + throw new GameFrameworkException("Parent entity is invalid."); + } + + return GetChildEntity(parentEntity.Id); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + public IEntity[] GetChildEntities(int parentEntityId) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); + } + + return parentEntityInfo.GetChildEntities(); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + public void GetChildEntities(int parentEntityId, List results) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); + } + + parentEntityInfo.GetChildEntities(results); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + public IEntity[] GetChildEntities(IEntity parentEntity) + { + if (parentEntity == null) + { + throw new GameFrameworkException("Parent entity is invalid."); + } + + return GetChildEntities(parentEntity.Id); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + public void GetChildEntities(IEntity parentEntity, List results) + { + if (parentEntity == null) + { + throw new GameFrameworkException("Parent entity is invalid."); + } + + GetChildEntities(parentEntity.Id, results); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + public void AttachEntity(int childEntityId, int parentEntityId) + { + AttachEntity(childEntityId, parentEntityId, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, int parentEntityId, object userData) + { + if (childEntityId == parentEntityId) + { + throw new GameFrameworkException(Utility.Text.Format("Can not attach entity when child entity id equals to parent entity id '{0}'.", parentEntityId)); + } + + EntityInfo childEntityInfo = GetEntityInfo(childEntityId); + if (childEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find child entity '{0}'.", childEntityId)); + } + + if (childEntityInfo.Status >= EntityStatus.WillHide) + { + throw new GameFrameworkException(Utility.Text.Format("Can not attach entity when child entity status is '{0}'.", childEntityInfo.Status)); + } + + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); + } + + if (parentEntityInfo.Status >= EntityStatus.WillHide) + { + throw new GameFrameworkException(Utility.Text.Format("Can not attach entity when parent entity status is '{0}'.", parentEntityInfo.Status)); + } + + IEntity childEntity = childEntityInfo.Entity; + IEntity parentEntity = parentEntityInfo.Entity; + DetachEntity(childEntity.Id, userData); + childEntityInfo.ParentEntity = parentEntity; + parentEntityInfo.AddChildEntity(childEntity); + parentEntity.OnAttached(childEntity, userData); + childEntity.OnAttachTo(parentEntity, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + public void AttachEntity(int childEntityId, IEntity parentEntity) + { + AttachEntity(childEntityId, parentEntity, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, IEntity parentEntity, object userData) + { + if (parentEntity == null) + { + throw new GameFrameworkException("Parent entity is invalid."); + } + + AttachEntity(childEntityId, parentEntity.Id, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + public void AttachEntity(IEntity childEntity, int parentEntityId) + { + AttachEntity(childEntity, parentEntityId, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + public void AttachEntity(IEntity childEntity, int parentEntityId, object userData) + { + if (childEntity == null) + { + throw new GameFrameworkException("Child entity is invalid."); + } + + AttachEntity(childEntity.Id, parentEntityId, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + public void AttachEntity(IEntity childEntity, IEntity parentEntity) + { + AttachEntity(childEntity, parentEntity, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 用户自定义数据。 + public void AttachEntity(IEntity childEntity, IEntity parentEntity, object userData) + { + if (childEntity == null) + { + throw new GameFrameworkException("Child entity is invalid."); + } + + if (parentEntity == null) + { + throw new GameFrameworkException("Parent entity is invalid."); + } + + AttachEntity(childEntity.Id, parentEntity.Id, userData); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + public void DetachEntity(int childEntityId) + { + DetachEntity(childEntityId, null); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + /// 用户自定义数据。 + public void DetachEntity(int childEntityId, object userData) + { + EntityInfo childEntityInfo = GetEntityInfo(childEntityId); + if (childEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find child entity '{0}'.", childEntityId)); + } + + IEntity parentEntity = childEntityInfo.ParentEntity; + if (parentEntity == null) + { + return; + } + + EntityInfo parentEntityInfo = GetEntityInfo(parentEntity.Id); + if (parentEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntity.Id)); + } + + IEntity childEntity = childEntityInfo.Entity; + childEntityInfo.ParentEntity = null; + parentEntityInfo.RemoveChildEntity(childEntity); + parentEntity.OnDetached(childEntity, userData); + childEntity.OnDetachFrom(parentEntity, userData); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + public void DetachEntity(IEntity childEntity) + { + DetachEntity(childEntity, null); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + /// 用户自定义数据。 + public void DetachEntity(IEntity childEntity, object userData) + { + if (childEntity == null) + { + throw new GameFrameworkException("Child entity is invalid."); + } + + DetachEntity(childEntity.Id, userData); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + public void DetachChildEntities(int parentEntityId) + { + DetachChildEntities(parentEntityId, null); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + /// 用户自定义数据。 + public void DetachChildEntities(int parentEntityId, object userData) + { + EntityInfo parentEntityInfo = GetEntityInfo(parentEntityId); + if (parentEntityInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find parent entity '{0}'.", parentEntityId)); + } + + while (parentEntityInfo.ChildEntityCount > 0) + { + IEntity childEntity = parentEntityInfo.GetChildEntity(); + DetachEntity(childEntity.Id, userData); + } + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + public void DetachChildEntities(IEntity parentEntity) + { + DetachChildEntities(parentEntity, null); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + public void DetachChildEntities(IEntity parentEntity, object userData) + { + if (parentEntity == null) + { + throw new GameFrameworkException("Parent entity is invalid."); + } + + DetachChildEntities(parentEntity.Id, userData); + } + + /// + /// 获取实体信息。 + /// + /// 实体编号。 + /// 实体信息。 + private EntityInfo GetEntityInfo(int entityId) + { + EntityInfo entityInfo = null; + if (m_EntityInfos.TryGetValue(entityId, out entityInfo)) + { + return entityInfo; + } + + return null; + } + + private void InternalShowEntity(int entityId, string entityAssetName, EntityGroup entityGroup, object entityInstance, bool isNewInstance, float duration, object userData) + { + try + { + IEntity entity = m_EntityHelper.CreateEntity(entityInstance, entityGroup, userData); + if (entity == null) + { + throw new GameFrameworkException("Can not create entity in entity helper."); + } + + EntityInfo entityInfo = EntityInfo.Create(entity); + m_EntityInfos.Add(entityId, entityInfo); + entityInfo.Status = EntityStatus.WillInit; + entity.OnInit(entityId, entityAssetName, entityGroup, isNewInstance, userData); + entityInfo.Status = EntityStatus.Inited; + entityGroup.AddEntity(entity); + entityInfo.Status = EntityStatus.WillShow; + entity.OnShow(userData); + entityInfo.Status = EntityStatus.Showed; + + if (m_ShowEntitySuccessEventHandler != null) + { + ShowEntitySuccessEventArgs showEntitySuccessEventArgs = ShowEntitySuccessEventArgs.Create(entity, duration, userData); + m_ShowEntitySuccessEventHandler(this, showEntitySuccessEventArgs); + ReferencePool.Release(showEntitySuccessEventArgs); + } + } + catch (Exception exception) + { + if (m_ShowEntityFailureEventHandler != null) + { + ShowEntityFailureEventArgs showEntityFailureEventArgs = ShowEntityFailureEventArgs.Create(entityId, entityAssetName, entityGroup.Name, exception.ToString(), userData); + m_ShowEntityFailureEventHandler(this, showEntityFailureEventArgs); + ReferencePool.Release(showEntityFailureEventArgs); + return; + } + + throw; + } + } + + private void InternalHideEntity(EntityInfo entityInfo, object userData) + { + while (entityInfo.ChildEntityCount > 0) + { + IEntity childEntity = entityInfo.GetChildEntity(); + HideEntity(childEntity.Id, userData); + } + + if (entityInfo.Status == EntityStatus.Hidden) + { + return; + } + + IEntity entity = entityInfo.Entity; + DetachEntity(entity.Id, userData); + entityInfo.Status = EntityStatus.WillHide; + entity.OnHide(m_IsShutdown, userData); + entityInfo.Status = EntityStatus.Hidden; + + EntityGroup entityGroup = (EntityGroup)entity.EntityGroup; + if (entityGroup == null) + { + throw new GameFrameworkException("Entity group is invalid."); + } + + entityGroup.RemoveEntity(entity); + if (!m_EntityInfos.Remove(entity.Id)) + { + throw new GameFrameworkException("Entity info is unmanaged."); + } + + if (m_HideEntityCompleteEventHandler != null) + { + HideEntityCompleteEventArgs hideEntityCompleteEventArgs = HideEntityCompleteEventArgs.Create(entity.Id, entity.EntityAssetName, entityGroup, userData); + m_HideEntityCompleteEventHandler(this, hideEntityCompleteEventArgs); + ReferencePool.Release(hideEntityCompleteEventArgs); + } + + m_RecycleQueue.Enqueue(entityInfo); + } + + private void LoadAssetSuccessCallback(string entityAssetName, object entityAsset, float duration, object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + if (showEntityInfo == null) + { + throw new GameFrameworkException("Show entity info is invalid."); + } + + if (m_EntitiesToReleaseOnLoad.Contains(showEntityInfo.SerialId)) + { + m_EntitiesToReleaseOnLoad.Remove(showEntityInfo.SerialId); + ReferencePool.Release(showEntityInfo); + m_EntityHelper.ReleaseEntity(entityAsset, null); + return; + } + + m_EntitiesBeingLoaded.Remove(showEntityInfo.EntityId); + EntityInstanceObject entityInstanceObject = EntityInstanceObject.Create(entityAssetName, entityAsset, m_EntityHelper.InstantiateEntity(entityAsset), m_EntityHelper); + showEntityInfo.EntityGroup.RegisterEntityInstanceObject(entityInstanceObject, true); + + InternalShowEntity(showEntityInfo.EntityId, entityAssetName, showEntityInfo.EntityGroup, entityInstanceObject.Target, true, duration, showEntityInfo.UserData); + ReferencePool.Release(showEntityInfo); + } + + private void LoadAssetFailureCallback(string entityAssetName, LoadResourceStatus status, string errorMessage, object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + if (showEntityInfo == null) + { + throw new GameFrameworkException("Show entity info is invalid."); + } + + if (m_EntitiesToReleaseOnLoad.Contains(showEntityInfo.SerialId)) + { + m_EntitiesToReleaseOnLoad.Remove(showEntityInfo.SerialId); + return; + } + + m_EntitiesBeingLoaded.Remove(showEntityInfo.EntityId); + string appendErrorMessage = Utility.Text.Format("Load entity failure, asset name '{0}', status '{1}', error message '{2}'.", entityAssetName, status, errorMessage); + if (m_ShowEntityFailureEventHandler != null) + { + ShowEntityFailureEventArgs showEntityFailureEventArgs = ShowEntityFailureEventArgs.Create(showEntityInfo.EntityId, entityAssetName, showEntityInfo.EntityGroup.Name, appendErrorMessage, showEntityInfo.UserData); + m_ShowEntityFailureEventHandler(this, showEntityFailureEventArgs); + ReferencePool.Release(showEntityFailureEventArgs); + return; + } + + throw new GameFrameworkException(appendErrorMessage); + } + + private void LoadAssetUpdateCallback(string entityAssetName, float progress, object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + if (showEntityInfo == null) + { + throw new GameFrameworkException("Show entity info is invalid."); + } + + if (m_ShowEntityUpdateEventHandler != null) + { + ShowEntityUpdateEventArgs showEntityUpdateEventArgs = ShowEntityUpdateEventArgs.Create(showEntityInfo.EntityId, entityAssetName, showEntityInfo.EntityGroup.Name, progress, showEntityInfo.UserData); + m_ShowEntityUpdateEventHandler(this, showEntityUpdateEventArgs); + ReferencePool.Release(showEntityUpdateEventArgs); + } + } + + private void LoadAssetDependencyAssetCallback(string entityAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + if (showEntityInfo == null) + { + throw new GameFrameworkException("Show entity info is invalid."); + } + + if (m_ShowEntityDependencyAssetEventHandler != null) + { + ShowEntityDependencyAssetEventArgs showEntityDependencyAssetEventArgs = ShowEntityDependencyAssetEventArgs.Create(showEntityInfo.EntityId, entityAssetName, showEntityInfo.EntityGroup.Name, dependencyAssetName, loadedCount, totalCount, showEntityInfo.UserData); + m_ShowEntityDependencyAssetEventHandler(this, showEntityDependencyAssetEventArgs); + ReferencePool.Release(showEntityDependencyAssetEventArgs); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.cs.meta new file mode 100644 index 0000000..8637a41 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/EntityManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eee578270537c0c40af3759c88085583 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/HideEntityCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/HideEntityCompleteEventArgs.cs new file mode 100644 index 0000000..04d421d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/HideEntityCompleteEventArgs.cs @@ -0,0 +1,91 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + /// + /// 隐藏实体完成事件。 + /// + public sealed class HideEntityCompleteEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化隐藏实体完成事件的新实例。 + /// + public HideEntityCompleteEventArgs() + { + EntityId = 0; + EntityAssetName = null; + EntityGroup = null; + UserData = null; + } + + /// + /// 获取实体编号。 + /// + public int EntityId + { + get; + private set; + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get; + private set; + } + + /// + /// 获取实体所属的实体组。 + /// + public IEntityGroup EntityGroup + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建隐藏实体完成事件。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体所属的实体组。 + /// 用户自定义数据。 + /// 创建的隐藏实体完成事件。 + public static HideEntityCompleteEventArgs Create(int entityId, string entityAssetName, IEntityGroup entityGroup, object userData) + { + HideEntityCompleteEventArgs hideEntityCompleteEventArgs = ReferencePool.Acquire(); + hideEntityCompleteEventArgs.EntityId = entityId; + hideEntityCompleteEventArgs.EntityAssetName = entityAssetName; + hideEntityCompleteEventArgs.EntityGroup = entityGroup; + hideEntityCompleteEventArgs.UserData = userData; + return hideEntityCompleteEventArgs; + } + + /// + /// 清理隐藏实体完成事件。 + /// + public override void Clear() + { + EntityId = 0; + EntityAssetName = null; + EntityGroup = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/HideEntityCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/HideEntityCompleteEventArgs.cs.meta new file mode 100644 index 0000000..449b0b4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/HideEntityCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b474b837c539cdf4c9316bf47ed22f06 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntity.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntity.cs new file mode 100644 index 0000000..d40e2cc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntity.cs @@ -0,0 +1,110 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + /// + /// 实体接口。 + /// + public interface IEntity + { + /// + /// 获取实体编号。 + /// + int Id + { + get; + } + + /// + /// 获取实体资源名称。 + /// + string EntityAssetName + { + get; + } + + /// + /// 获取实体实例。 + /// + object Handle + { + get; + } + + /// + /// 获取实体所属的实体组。 + /// + IEntityGroup EntityGroup + { + get; + } + + /// + /// 实体初始化。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体所属的实体组。 + /// 是否是新实例。 + /// 用户自定义数据。 + void OnInit(int entityId, string entityAssetName, IEntityGroup entityGroup, bool isNewInstance, object userData); + + /// + /// 实体回收。 + /// + void OnRecycle(); + + /// + /// 实体显示。 + /// + /// 用户自定义数据。 + void OnShow(object userData); + + /// + /// 实体隐藏。 + /// + /// 是否是关闭实体管理器时触发。 + /// 用户自定义数据。 + void OnHide(bool isShutdown, object userData); + + /// + /// 实体附加子实体。 + /// + /// 附加的子实体。 + /// 用户自定义数据。 + void OnAttached(IEntity childEntity, object userData); + + /// + /// 实体解除子实体。 + /// + /// 解除的子实体。 + /// 用户自定义数据。 + void OnDetached(IEntity childEntity, object userData); + + /// + /// 实体附加子实体。 + /// + /// 被附加的父实体。 + /// 用户自定义数据。 + void OnAttachTo(IEntity parentEntity, object userData); + + /// + /// 实体解除子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + void OnDetachFrom(IEntity parentEntity, object userData); + + /// + /// 实体轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + void OnUpdate(float elapseSeconds, float realElapseSeconds); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntity.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntity.cs.meta new file mode 100644 index 0000000..ab48454 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e9325b75955dd74e95ae66daf83152b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroup.cs new file mode 100644 index 0000000..0b14855 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroup.cs @@ -0,0 +1,145 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Entity +{ + /// + /// 实体组接口。 + /// + public interface IEntityGroup + { + /// + /// 获取实体组名称。 + /// + string Name + { + get; + } + + /// + /// 获取实体组中实体数量。 + /// + int EntityCount + { + get; + } + + /// + /// 获取或设置实体组实例对象池自动释放可释放对象的间隔秒数。 + /// + float InstanceAutoReleaseInterval + { + get; + set; + } + + /// + /// 获取或设置实体组实例对象池的容量。 + /// + int InstanceCapacity + { + get; + set; + } + + /// + /// 获取或设置实体组实例对象池对象过期秒数。 + /// + float InstanceExpireTime + { + get; + set; + } + + /// + /// 获取或设置实体组实例对象池的优先级。 + /// + int InstancePriority + { + get; + set; + } + + /// + /// 获取实体组辅助器。 + /// + IEntityGroupHelper Helper + { + get; + } + + /// + /// 实体组中是否存在实体。 + /// + /// 实体序列编号。 + /// 实体组中是否存在实体。 + bool HasEntity(int entityId); + + /// + /// 实体组中是否存在实体。 + /// + /// 实体资源名称。 + /// 实体组中是否存在实体。 + bool HasEntity(string entityAssetName); + + /// + /// 从实体组中获取实体。 + /// + /// 实体序列编号。 + /// 要获取的实体。 + IEntity GetEntity(int entityId); + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + IEntity GetEntity(string entityAssetName); + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + IEntity[] GetEntities(string entityAssetName); + + /// + /// 从实体组中获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + void GetEntities(string entityAssetName, List results); + + /// + /// 从实体组中获取所有实体。 + /// + /// 实体组中的所有实体。 + IEntity[] GetAllEntities(); + + /// + /// 从实体组中获取所有实体。 + /// + /// 实体组中的所有实体。 + void GetAllEntities(List results); + + /// + /// 设置实体实例是否被加锁。 + /// + /// 实体实例。 + /// 实体实例是否被加锁。 + void SetEntityInstanceLocked(object entityInstance, bool locked); + + /// + /// 设置实体实例的优先级。 + /// + /// 实体实例。 + /// 实体实例优先级。 + void SetEntityInstancePriority(object entityInstance, int priority); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroup.cs.meta new file mode 100644 index 0000000..c71ff6f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f78f0cfcfbd44cf48902c7d9eb72932d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroupHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroupHelper.cs new file mode 100644 index 0000000..fe58e00 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroupHelper.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + /// + /// 实体组辅助器接口。 + /// + public interface IEntityGroupHelper + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroupHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroupHelper.cs.meta new file mode 100644 index 0000000..5346fe7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityGroupHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cadd2228fcd4e884c97821773e45413d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityHelper.cs new file mode 100644 index 0000000..4caeba4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityHelper.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + /// + /// 实体辅助器接口。 + /// + public interface IEntityHelper + { + /// + /// 实例化实体。 + /// + /// 要实例化的实体资源。 + /// 实例化后的实体。 + object InstantiateEntity(object entityAsset); + + /// + /// 创建实体。 + /// + /// 实体实例。 + /// 实体所属的实体组。 + /// 用户自定义数据。 + /// 实体。 + IEntity CreateEntity(object entityInstance, IEntityGroup entityGroup, object userData); + + /// + /// 释放实体。 + /// + /// 要释放的实体资源。 + /// 要释放的实体实例。 + void ReleaseEntity(object entityAsset, object entityInstance); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityHelper.cs.meta new file mode 100644 index 0000000..4337ae2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f2b89f697c0c2424f85ffaf83748f770 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityManager.cs new file mode 100644 index 0000000..f5b59f2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityManager.cs @@ -0,0 +1,450 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.Entity +{ + /// + /// 实体管理器接口。 + /// + public interface IEntityManager + { + /// + /// 获取实体数量。 + /// + int EntityCount + { + get; + } + + /// + /// 获取实体组数量。 + /// + int EntityGroupCount + { + get; + } + + /// + /// 显示实体成功事件。 + /// + event EventHandler ShowEntitySuccess; + + /// + /// 显示实体失败事件。 + /// + event EventHandler ShowEntityFailure; + + /// + /// 显示实体更新事件。 + /// + event EventHandler ShowEntityUpdate; + + /// + /// 显示实体时加载依赖资源事件。 + /// + event EventHandler ShowEntityDependencyAsset; + + /// + /// 隐藏实体完成事件。 + /// + event EventHandler HideEntityComplete; + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + void SetObjectPoolManager(IObjectPoolManager objectPoolManager); + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + void SetResourceManager(IResourceManager resourceManager); + + /// + /// 设置实体辅助器。 + /// + /// 实体辅助器。 + void SetEntityHelper(IEntityHelper entityHelper); + + /// + /// 是否存在实体组。 + /// + /// 实体组名称。 + /// 是否存在实体组。 + bool HasEntityGroup(string entityGroupName); + + /// + /// 获取实体组。 + /// + /// 实体组名称。 + /// 要获取的实体组。 + IEntityGroup GetEntityGroup(string entityGroupName); + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + IEntityGroup[] GetAllEntityGroups(); + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + void GetAllEntityGroups(List results); + + /// + /// 增加实体组。 + /// + /// 实体组名称。 + /// 实体实例对象池自动释放可释放对象的间隔秒数。 + /// 实体实例对象池容量。 + /// 实体实例对象池对象过期秒数。 + /// 实体实例对象池的优先级。 + /// 实体组辅助器。 + /// 是否增加实体组成功。 + bool AddEntityGroup(string entityGroupName, float instanceAutoReleaseInterval, int instanceCapacity, float instanceExpireTime, int instancePriority, IEntityGroupHelper entityGroupHelper); + + /// + /// 是否存在实体。 + /// + /// 实体编号。 + /// 是否存在实体。 + bool HasEntity(int entityId); + + /// + /// 是否存在实体。 + /// + /// 实体资源名称。 + /// 是否存在实体。 + bool HasEntity(string entityAssetName); + + /// + /// 获取实体。 + /// + /// 实体编号。 + /// 要获取的实体。 + IEntity GetEntity(int entityId); + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + IEntity GetEntity(string entityAssetName); + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + IEntity[] GetEntities(string entityAssetName); + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + void GetEntities(string entityAssetName, List results); + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + IEntity[] GetAllLoadedEntities(); + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + void GetAllLoadedEntities(List results); + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + int[] GetAllLoadingEntityIds(); + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + void GetAllLoadingEntityIds(List results); + + /// + /// 是否正在加载实体。 + /// + /// 实体编号。 + /// 是否正在加载实体。 + bool IsLoadingEntity(int entityId); + + /// + /// 是否是合法的实体。 + /// + /// 实体。 + /// 实体是否合法。 + bool IsValidEntity(IEntity entity); + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + void ShowEntity(int entityId, string entityAssetName, string entityGroupName); + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority); + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 用户自定义数据。 + void ShowEntity(int entityId, string entityAssetName, string entityGroupName, object userData); + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + /// 用户自定义数据。 + void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority, object userData); + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + void HideEntity(int entityId); + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + /// 用户自定义数据。 + void HideEntity(int entityId, object userData); + + /// + /// 隐藏实体。 + /// + /// 实体。 + void HideEntity(IEntity entity); + + /// + /// 隐藏实体。 + /// + /// 实体。 + /// 用户自定义数据。 + void HideEntity(IEntity entity, object userData); + + /// + /// 隐藏所有已加载的实体。 + /// + void HideAllLoadedEntities(); + + /// + /// 隐藏所有已加载的实体。 + /// + /// 用户自定义数据。 + void HideAllLoadedEntities(object userData); + + /// + /// 隐藏所有正在加载的实体。 + /// + void HideAllLoadingEntities(); + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体的实体编号。 + /// 子实体的父实体。 + IEntity GetParentEntity(int childEntityId); + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体。 + /// 子实体的父实体。 + IEntity GetParentEntity(IEntity childEntity); + + /// + /// 获取子实体数量。 + /// + /// 要获取子实体数量的父实体的实体编号。 + /// 子实体数量。 + int GetChildEntityCount(int parentEntityId); + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体的实体编号。 + /// 子实体。 + IEntity GetChildEntity(int parentEntityId); + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体。 + /// 子实体。 + IEntity GetChildEntity(IEntity parentEntity); + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + IEntity[] GetChildEntities(int parentEntityId); + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + void GetChildEntities(int parentEntityId, List results); + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + IEntity[] GetChildEntities(IEntity parentEntity); + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + void GetChildEntities(IEntity parentEntity, List results); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + void AttachEntity(int childEntityId, int parentEntityId); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + void AttachEntity(int childEntityId, int parentEntityId, object userData); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + void AttachEntity(int childEntityId, IEntity parentEntity); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 用户自定义数据。 + void AttachEntity(int childEntityId, IEntity parentEntity, object userData); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + void AttachEntity(IEntity childEntity, int parentEntityId); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + void AttachEntity(IEntity childEntity, int parentEntityId, object userData); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + void AttachEntity(IEntity childEntity, IEntity parentEntity); + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 用户自定义数据。 + void AttachEntity(IEntity childEntity, IEntity parentEntity, object userData); + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + void DetachEntity(int childEntityId); + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + /// 用户自定义数据。 + void DetachEntity(int childEntityId, object userData); + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + void DetachEntity(IEntity childEntity); + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + /// 用户自定义数据。 + void DetachEntity(IEntity childEntity, object userData); + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + void DetachChildEntities(int parentEntityId); + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + /// 用户自定义数据。 + void DetachChildEntities(int parentEntityId, object userData); + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + void DetachChildEntities(IEntity parentEntity); + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + void DetachChildEntities(IEntity parentEntity, object userData); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityManager.cs.meta new file mode 100644 index 0000000..795f83c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/IEntityManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af86c0d3edb7a334f9bf80e25c54393e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs new file mode 100644 index 0000000..41453f5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs @@ -0,0 +1,130 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + /// + /// 显示实体时加载依赖资源事件。 + /// + public sealed class ShowEntityDependencyAssetEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化显示实体时加载依赖资源事件的新实例。 + /// + public ShowEntityDependencyAssetEventArgs() + { + EntityId = 0; + EntityAssetName = null; + EntityGroupName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取实体编号。 + /// + public int EntityId + { + get; + private set; + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get; + private set; + } + + /// + /// 获取实体组名称。 + /// + public string EntityGroupName + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建显示实体时加载依赖资源事件。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 被加载的依赖资源名称。 + /// 当前已加载依赖资源数量。 + /// 总共加载依赖资源数量。 + /// 用户自定义数据。 + /// 创建的显示实体时加载依赖资源事件。 + public static ShowEntityDependencyAssetEventArgs Create(int entityId, string entityAssetName, string entityGroupName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + ShowEntityDependencyAssetEventArgs showEntityDependencyAssetEventArgs = ReferencePool.Acquire(); + showEntityDependencyAssetEventArgs.EntityId = entityId; + showEntityDependencyAssetEventArgs.EntityAssetName = entityAssetName; + showEntityDependencyAssetEventArgs.EntityGroupName = entityGroupName; + showEntityDependencyAssetEventArgs.DependencyAssetName = dependencyAssetName; + showEntityDependencyAssetEventArgs.LoadedCount = loadedCount; + showEntityDependencyAssetEventArgs.TotalCount = totalCount; + showEntityDependencyAssetEventArgs.UserData = userData; + return showEntityDependencyAssetEventArgs; + } + + /// + /// 清理显示实体时加载依赖资源事件。 + /// + public override void Clear() + { + EntityId = 0; + EntityAssetName = null; + EntityGroupName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..b66b5de --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c29f7f51222af0341a969a26afe74341 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityFailureEventArgs.cs new file mode 100644 index 0000000..4f63476 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityFailureEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + /// + /// 显示实体失败事件。 + /// + public sealed class ShowEntityFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化显示实体失败事件的新实例。 + /// + public ShowEntityFailureEventArgs() + { + EntityId = 0; + EntityAssetName = null; + EntityGroupName = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取实体编号。 + /// + public int EntityId + { + get; + private set; + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get; + private set; + } + + /// + /// 获取实体组名称。 + /// + public string EntityGroupName + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建显示实体失败事件。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 错误信息。 + /// 用户自定义数据。 + /// 创建的显示实体失败事件。 + public static ShowEntityFailureEventArgs Create(int entityId, string entityAssetName, string entityGroupName, string errorMessage, object userData) + { + ShowEntityFailureEventArgs showEntityFailureEventArgs = ReferencePool.Acquire(); + showEntityFailureEventArgs.EntityId = entityId; + showEntityFailureEventArgs.EntityAssetName = entityAssetName; + showEntityFailureEventArgs.EntityGroupName = entityGroupName; + showEntityFailureEventArgs.ErrorMessage = errorMessage; + showEntityFailureEventArgs.UserData = userData; + return showEntityFailureEventArgs; + } + + /// + /// 清理显示实体失败事件。 + /// + public override void Clear() + { + EntityId = 0; + EntityAssetName = null; + EntityGroupName = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityFailureEventArgs.cs.meta new file mode 100644 index 0000000..4d0eb8e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c68aefb100bc724ca3ff7106978d008 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntitySuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntitySuccessEventArgs.cs new file mode 100644 index 0000000..7928977 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntitySuccessEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + /// + /// 显示实体成功事件。 + /// + public sealed class ShowEntitySuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化显示实体成功事件的新实例。 + /// + public ShowEntitySuccessEventArgs() + { + Entity = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取显示成功的实体。 + /// + public IEntity Entity + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建显示实体成功事件。 + /// + /// 加载成功的实体。 + /// 加载持续时间。 + /// 用户自定义数据。 + /// 创建的显示实体成功事件。 + public static ShowEntitySuccessEventArgs Create(IEntity entity, float duration, object userData) + { + ShowEntitySuccessEventArgs showEntitySuccessEventArgs = ReferencePool.Acquire(); + showEntitySuccessEventArgs.Entity = entity; + showEntitySuccessEventArgs.Duration = duration; + showEntitySuccessEventArgs.UserData = userData; + return showEntitySuccessEventArgs; + } + + /// + /// 清理显示实体成功事件。 + /// + public override void Clear() + { + Entity = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntitySuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntitySuccessEventArgs.cs.meta new file mode 100644 index 0000000..324c74e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntitySuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4637c464d89e11e42a2125e46d7b4fb3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityUpdateEventArgs.cs new file mode 100644 index 0000000..e24b9a0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityUpdateEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Entity +{ + /// + /// 显示实体更新事件。 + /// + public sealed class ShowEntityUpdateEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化显示实体更新事件的新实例。 + /// + public ShowEntityUpdateEventArgs() + { + EntityId = 0; + EntityAssetName = null; + EntityGroupName = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取实体编号。 + /// + public int EntityId + { + get; + private set; + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get; + private set; + } + + /// + /// 获取实体组名称。 + /// + public string EntityGroupName + { + get; + private set; + } + + /// + /// 获取显示实体进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建显示实体更新事件。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 显示实体进度。 + /// 用户自定义数据。 + /// 创建的显示实体更新事件。 + public static ShowEntityUpdateEventArgs Create(int entityId, string entityAssetName, string entityGroupName, float progress, object userData) + { + ShowEntityUpdateEventArgs showEntityUpdateEventArgs = ReferencePool.Acquire(); + showEntityUpdateEventArgs.EntityId = entityId; + showEntityUpdateEventArgs.EntityAssetName = entityAssetName; + showEntityUpdateEventArgs.EntityGroupName = entityGroupName; + showEntityUpdateEventArgs.Progress = progress; + showEntityUpdateEventArgs.UserData = userData; + return showEntityUpdateEventArgs; + } + + /// + /// 清理显示实体更新事件。 + /// + public override void Clear() + { + EntityId = 0; + EntityAssetName = null; + EntityGroupName = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityUpdateEventArgs.cs.meta new file mode 100644 index 0000000..adf95e8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Entity/ShowEntityUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11d44af5d8234634db75a886ac49bd38 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event.meta new file mode 100644 index 0000000..27485f0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fe4730f3ed4392c488fb14d1d8528085 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/EventManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/EventManager.cs new file mode 100644 index 0000000..fcf6451 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/EventManager.cs @@ -0,0 +1,149 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.Event +{ + /// + /// 事件管理器。 + /// + internal sealed class EventManager : GameFrameworkModule, IEventManager + { + private readonly EventPool m_EventPool; + + /// + /// 初始化事件管理器的新实例。 + /// + public EventManager() + { + m_EventPool = new EventPool(EventPoolMode.AllowNoHandler | EventPoolMode.AllowMultiHandler); + } + + /// + /// 获取事件处理函数的数量。 + /// + public int EventHandlerCount + { + get + { + return m_EventPool.EventHandlerCount; + } + } + + /// + /// 获取事件数量。 + /// + public int EventCount + { + get + { + return m_EventPool.EventCount; + } + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return 7; + } + } + + /// + /// 事件管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + m_EventPool.Update(elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理事件管理器。 + /// + internal override void Shutdown() + { + m_EventPool.Shutdown(); + } + + /// + /// 获取事件处理函数的数量。 + /// + /// 事件类型编号。 + /// 事件处理函数的数量。 + public int Count(int id) + { + return m_EventPool.Count(id); + } + + /// + /// 检查是否存在事件处理函数。 + /// + /// 事件类型编号。 + /// 要检查的事件处理函数。 + /// 是否存在事件处理函数。 + public bool Check(int id, EventHandler handler) + { + return m_EventPool.Check(id, handler); + } + + /// + /// 订阅事件处理函数。 + /// + /// 事件类型编号。 + /// 要订阅的事件处理函数。 + public void Subscribe(int id, EventHandler handler) + { + m_EventPool.Subscribe(id, handler); + } + + /// + /// 取消订阅事件处理函数。 + /// + /// 事件类型编号。 + /// 要取消订阅的事件处理函数。 + public void Unsubscribe(int id, EventHandler handler) + { + m_EventPool.Unsubscribe(id, handler); + } + + /// + /// 设置默认事件处理函数。 + /// + /// 要设置的默认事件处理函数。 + public void SetDefaultHandler(EventHandler handler) + { + m_EventPool.SetDefaultHandler(handler); + } + + /// + /// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。 + /// + /// 事件源。 + /// 事件参数。 + public void Fire(object sender, GameEventArgs e) + { + m_EventPool.Fire(sender, e); + } + + /// + /// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。 + /// + /// 事件源。 + /// 事件参数。 + public void FireNow(object sender, GameEventArgs e) + { + m_EventPool.FireNow(sender, e); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/EventManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/EventManager.cs.meta new file mode 100644 index 0000000..5aefea9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/EventManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3969249ba61301478e1f8c0d86944c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/GameEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/GameEventArgs.cs new file mode 100644 index 0000000..6c04619 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/GameEventArgs.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Event +{ + /// + /// 游戏逻辑事件基类。 + /// + public abstract class GameEventArgs : BaseEventArgs + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/GameEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/GameEventArgs.cs.meta new file mode 100644 index 0000000..111a40d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/GameEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 276f510fe7a726442af464e396fba336 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/IEventManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/IEventManager.cs new file mode 100644 index 0000000..02d0f6a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/IEventManager.cs @@ -0,0 +1,82 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.Event +{ + /// + /// 事件管理器接口。 + /// + public interface IEventManager + { + /// + /// 获取事件处理函数的数量。 + /// + int EventHandlerCount + { + get; + } + + /// + /// 获取事件数量。 + /// + int EventCount + { + get; + } + + /// + /// 获取事件处理函数的数量。 + /// + /// 事件类型编号。 + /// 事件处理函数的数量。 + int Count(int id); + + /// + /// 检查是否存在事件处理函数。 + /// + /// 事件类型编号。 + /// 要检查的事件处理函数。 + /// 是否存在事件处理函数。 + bool Check(int id, EventHandler handler); + + /// + /// 订阅事件处理函数。 + /// + /// 事件类型编号。 + /// 要订阅的事件处理函数。 + void Subscribe(int id, EventHandler handler); + + /// + /// 取消订阅事件处理函数。 + /// + /// 事件类型编号。 + /// 要取消订阅的事件处理函数。 + void Unsubscribe(int id, EventHandler handler); + + /// + /// 设置默认事件处理函数。 + /// + /// 要设置的默认事件处理函数。 + void SetDefaultHandler(EventHandler handler); + + /// + /// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。 + /// + /// 事件源。 + /// 事件参数。 + void Fire(object sender, GameEventArgs e); + + /// + /// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。 + /// + /// 事件源。 + /// 事件参数。 + void FireNow(object sender, GameEventArgs e); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/IEventManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/IEventManager.cs.meta new file mode 100644 index 0000000..7b2e98a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Event/IEventManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e67fdaacf6818b140b13b20e72e380dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem.meta new file mode 100644 index 0000000..87f6f54 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a82daa71a1304224eaeccf3065f59a7d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/CommonFileSystemStream.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/CommonFileSystemStream.cs new file mode 100644 index 0000000..4ca7d14 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/CommonFileSystemStream.cs @@ -0,0 +1,162 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.IO; + +namespace GameFramework.FileSystem +{ + /// + /// 通用文件系统流。 + /// + public sealed class CommonFileSystemStream : FileSystemStream, IDisposable + { + private readonly FileStream m_FileStream; + + /// + /// 初始化通用文件系统流的新实例。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 是否创建新的文件系统流。 + public CommonFileSystemStream(string fullPath, FileSystemAccess access, bool createNew) + { + if (string.IsNullOrEmpty(fullPath)) + { + throw new GameFrameworkException("Full path is invalid."); + } + + switch (access) + { + case FileSystemAccess.Read: + m_FileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read); + break; + + case FileSystemAccess.Write: + m_FileStream = new FileStream(fullPath, createNew ? FileMode.Create : FileMode.Open, FileAccess.Write, FileShare.Read); + break; + + case FileSystemAccess.ReadWrite: + m_FileStream = new FileStream(fullPath, createNew ? FileMode.Create : FileMode.Open, FileAccess.ReadWrite, FileShare.Read); + break; + + default: + throw new GameFrameworkException("Access is invalid."); + } + } + + /// + /// 获取或设置文件系统流位置。 + /// + public override long Position + { + get + { + return m_FileStream.Position; + } + set + { + m_FileStream.Position = value; + } + } + + /// + /// 获取文件系统流长度。 + /// + public override long Length + { + get + { + return m_FileStream.Length; + } + } + + /// + /// 设置文件系统流长度。 + /// + /// 要设置的文件系统流的长度。 + public override void SetLength(long length) + { + m_FileStream.SetLength(length); + } + + /// + /// 定位文件系统流位置。 + /// + /// 要定位的文件系统流位置的偏移。 + /// 要定位的文件系统流位置的方式。 + public override void Seek(long offset, SeekOrigin origin) + { + m_FileStream.Seek(offset, origin); + } + + /// + /// 从文件系统流中读取一个字节。 + /// + /// 读取的字节,若已经到达文件结尾,则返回 -1。 + public override int ReadByte() + { + return m_FileStream.ReadByte(); + } + + /// + /// 从文件系统流中读取二进制流。 + /// + /// 存储读取文件内容的二进制流。 + /// 存储读取文件内容的二进制流的起始位置。 + /// 存储读取文件内容的二进制流的长度。 + /// 实际读取了多少字节。 + public override int Read(byte[] buffer, int startIndex, int length) + { + return m_FileStream.Read(buffer, startIndex, length); + } + + /// + /// 向文件系统流中写入一个字节。 + /// + /// 要写入的字节。 + public override void WriteByte(byte value) + { + m_FileStream.WriteByte(value); + } + + /// + /// 向文件系统流中写入二进制流。 + /// + /// 存储写入文件内容的二进制流。 + /// 存储写入文件内容的二进制流的起始位置。 + /// 存储写入文件内容的二进制流的长度。 + public override void Write(byte[] buffer, int startIndex, int length) + { + m_FileStream.Write(buffer, startIndex, length); + } + + /// + /// 将文件系统流立刻更新到存储介质中。 + /// + public override void Flush() + { + m_FileStream.Flush(); + } + + /// + /// 关闭文件系统流。 + /// + public override void Close() + { + m_FileStream.Close(); + } + + /// + /// 销毁文件系统流。 + /// + public void Dispose() + { + m_FileStream.Dispose(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/CommonFileSystemStream.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/CommonFileSystemStream.cs.meta new file mode 100644 index 0000000..cf89b6d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/CommonFileSystemStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0009c925b8c6f646aa0604971a42813 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileInfo.cs new file mode 100644 index 0000000..8ad4895 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileInfo.cs @@ -0,0 +1,94 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.FileSystem +{ + /// + /// 文件信息。 + /// + [StructLayout(LayoutKind.Auto)] + public struct FileInfo + { + private readonly string m_Name; + private readonly long m_Offset; + private readonly int m_Length; + + /// + /// 初始化文件信息的新实例。 + /// + /// 文件名称。 + /// 文件偏移。 + /// 文件长度。 + public FileInfo(string name, long offset, int length) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (offset < 0L) + { + throw new GameFrameworkException("Offset is invalid."); + } + + if (length < 0) + { + throw new GameFrameworkException("Length is invalid."); + } + + m_Name = name; + m_Offset = offset; + m_Length = length; + } + + /// + /// 获取文件信息是否有效。 + /// + public bool IsValid + { + get + { + return !string.IsNullOrEmpty(m_Name) && m_Offset >= 0L && m_Length >= 0; + } + } + + /// + /// 获取文件名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取文件偏移。 + /// + public long Offset + { + get + { + return m_Offset; + } + } + + /// + /// 获取文件长度。 + /// + public int Length + { + get + { + return m_Length; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileInfo.cs.meta new file mode 100644 index 0000000..96fe25e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f925951dd3c2201418a72c3592fa64e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.BlockData.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.BlockData.cs new file mode 100644 index 0000000..6f75d9d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.BlockData.cs @@ -0,0 +1,76 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.FileSystem +{ + internal sealed partial class FileSystem : IFileSystem + { + /// + /// 块数据。 + /// + [StructLayout(LayoutKind.Sequential)] + private struct BlockData + { + public static readonly BlockData Empty = new BlockData(0, 0); + + private readonly int m_StringIndex; + private readonly int m_ClusterIndex; + private readonly int m_Length; + + public BlockData(int clusterIndex, int length) + : this(-1, clusterIndex, length) + { + } + + public BlockData(int stringIndex, int clusterIndex, int length) + { + m_StringIndex = stringIndex; + m_ClusterIndex = clusterIndex; + m_Length = length; + } + + public bool Using + { + get + { + return m_StringIndex >= 0; + } + } + + public int StringIndex + { + get + { + return m_StringIndex; + } + } + + public int ClusterIndex + { + get + { + return m_ClusterIndex; + } + } + + public int Length + { + get + { + return m_Length; + } + } + + public BlockData Free() + { + return new BlockData(m_ClusterIndex, (int)GetUpBoundClusterOffset(m_Length)); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.BlockData.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.BlockData.cs.meta new file mode 100644 index 0000000..c3b4fa4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.BlockData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 673f7b724e40aa34882b02487b912702 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.HeaderData.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.HeaderData.cs new file mode 100644 index 0000000..9428cd6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.HeaderData.cs @@ -0,0 +1,105 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.FileSystem +{ + internal sealed partial class FileSystem : IFileSystem + { + /// + /// 头数据。 + /// + [StructLayout(LayoutKind.Sequential)] + private struct HeaderData + { + private const int HeaderLength = 3; + private const int FileSystemVersion = 0; + private const int EncryptBytesLength = 4; + private static readonly byte[] Header = new byte[HeaderLength] { (byte)'G', (byte)'F', (byte)'F' }; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = HeaderLength)] + private readonly byte[] m_Header; + + private readonly byte m_Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = EncryptBytesLength)] + private readonly byte[] m_EncryptBytes; + + private readonly int m_MaxFileCount; + private readonly int m_MaxBlockCount; + private readonly int m_BlockCount; + + public HeaderData(int maxFileCount, int maxBlockCount) + : this(FileSystemVersion, new byte[EncryptBytesLength], maxFileCount, maxBlockCount, 0) + { + Utility.Random.GetRandomBytes(m_EncryptBytes); + } + + public HeaderData(byte version, byte[] encryptBytes, int maxFileCount, int maxBlockCount, int blockCount) + { + m_Header = Header; + m_Version = version; + m_EncryptBytes = encryptBytes; + m_MaxFileCount = maxFileCount; + m_MaxBlockCount = maxBlockCount; + m_BlockCount = blockCount; + } + + public bool IsValid + { + get + { + return m_Header.Length == HeaderLength && m_Header[0] == Header[0] && m_Header[1] == Header[1] && m_Header[2] == Header[2] && m_Version == FileSystemVersion && m_EncryptBytes.Length == EncryptBytesLength + && m_MaxFileCount > 0 && m_MaxBlockCount > 0 && m_MaxFileCount <= m_MaxBlockCount && m_BlockCount > 0 && m_BlockCount <= m_MaxBlockCount; + } + } + + public byte Version + { + get + { + return m_Version; + } + } + + public int MaxFileCount + { + get + { + return m_MaxFileCount; + } + } + + public int MaxBlockCount + { + get + { + return m_MaxBlockCount; + } + } + + public int BlockCount + { + get + { + return m_BlockCount; + } + } + + public byte[] GetEncryptBytes() + { + return m_EncryptBytes; + } + + public HeaderData SetBlockCount(int blockCount) + { + return new HeaderData(m_Version, m_EncryptBytes, m_MaxFileCount, m_MaxBlockCount, blockCount); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.HeaderData.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.HeaderData.cs.meta new file mode 100644 index 0000000..7041853 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.HeaderData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65f96dfcbe4107442afb1b46ac24a1bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.StringData.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.StringData.cs new file mode 100644 index 0000000..bc4b46b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.StringData.cs @@ -0,0 +1,70 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Runtime.InteropServices; + +namespace GameFramework.FileSystem +{ + internal sealed partial class FileSystem : IFileSystem + { + /// + /// 字符串数据。 + /// + [StructLayout(LayoutKind.Sequential)] + private struct StringData + { + private static readonly byte[] s_CachedBytes = new byte[byte.MaxValue + 1]; + + private readonly byte m_Length; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = byte.MaxValue)] + private readonly byte[] m_Bytes; + + public StringData(byte length, byte[] bytes) + { + m_Length = length; + m_Bytes = bytes; + } + + public string GetString(byte[] encryptBytes) + { + if (m_Length <= 0) + { + return null; + } + + Array.Copy(m_Bytes, 0, s_CachedBytes, 0, m_Length); + Utility.Encryption.GetSelfXorBytes(s_CachedBytes, 0, m_Length, encryptBytes); + return Utility.Converter.GetString(s_CachedBytes, 0, m_Length); + } + + public StringData SetString(string value, byte[] encryptBytes) + { + if (string.IsNullOrEmpty(value)) + { + return Clear(); + } + + int length = Utility.Converter.GetBytes(value, s_CachedBytes); + if (length > byte.MaxValue) + { + throw new GameFrameworkException(Utility.Text.Format("String '{0}' is too long.", value)); + } + + Utility.Encryption.GetSelfXorBytes(s_CachedBytes, encryptBytes); + Array.Copy(s_CachedBytes, 0, m_Bytes, 0, length); + return new StringData((byte)length, m_Bytes); + } + + public StringData Clear() + { + return new StringData(0, m_Bytes); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.StringData.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.StringData.cs.meta new file mode 100644 index 0000000..81361f3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.StringData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b63c47b17be2754380fb9201e7cb5e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.cs new file mode 100644 index 0000000..f1af280 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.cs @@ -0,0 +1,1381 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; + +namespace GameFramework.FileSystem +{ + /// + /// 文件系统。 + /// + internal sealed partial class FileSystem : IFileSystem + { + private const int ClusterSize = 1024 * 4; + private const int CachedBytesLength = 0x1000; + + private static readonly string[] EmptyStringArray = new string[] { }; + private static readonly byte[] s_CachedBytes = new byte[CachedBytesLength]; + + private static readonly int HeaderDataSize = Marshal.SizeOf(typeof(HeaderData)); + private static readonly int BlockDataSize = Marshal.SizeOf(typeof(BlockData)); + private static readonly int StringDataSize = Marshal.SizeOf(typeof(StringData)); + + private readonly string m_FullPath; + private readonly FileSystemAccess m_Access; + private readonly FileSystemStream m_Stream; + private readonly Dictionary m_FileDatas; + private readonly List m_BlockDatas; + private readonly GameFrameworkMultiDictionary m_FreeBlockIndexes; + private readonly SortedDictionary m_StringDatas; + private readonly Queue m_FreeStringIndexes; + private readonly Queue m_FreeStringDatas; + + private HeaderData m_HeaderData; + private int m_BlockDataOffset; + private int m_StringDataOffset; + private int m_FileDataOffset; + + /// + /// 初始化文件系统的新实例。 + /// + /// 文件系统完整路径。 + /// 文件系统访问方式。 + /// 文件系统流。 + private FileSystem(string fullPath, FileSystemAccess access, FileSystemStream stream) + { + if (string.IsNullOrEmpty(fullPath)) + { + throw new GameFrameworkException("Full path is invalid."); + } + + if (access == FileSystemAccess.Unspecified) + { + throw new GameFrameworkException("Access is invalid."); + } + + if (stream == null) + { + throw new GameFrameworkException("Stream is invalid."); + } + + m_FullPath = fullPath; + m_Access = access; + m_Stream = stream; + m_FileDatas = new Dictionary(StringComparer.Ordinal); + m_BlockDatas = new List(); + m_FreeBlockIndexes = new GameFrameworkMultiDictionary(); + m_StringDatas = new SortedDictionary(); + m_FreeStringIndexes = new Queue(); + m_FreeStringDatas = new Queue(); + + m_HeaderData = default(HeaderData); + m_BlockDataOffset = 0; + m_StringDataOffset = 0; + m_FileDataOffset = 0; + + Utility.Marshal.EnsureCachedHGlobalSize(CachedBytesLength); + } + + /// + /// 获取文件系统完整路径。 + /// + public string FullPath + { + get + { + return m_FullPath; + } + } + + /// + /// 获取文件系统访问方式。 + /// + public FileSystemAccess Access + { + get + { + return m_Access; + } + } + + /// + /// 获取文件数量。 + /// + public int FileCount + { + get + { + return m_FileDatas.Count; + } + } + + /// + /// 获取最大文件数量。 + /// + public int MaxFileCount + { + get + { + return m_HeaderData.MaxFileCount; + } + } + + /// + /// 创建文件系统。 + /// + /// 要创建的文件系统的完整路径。 + /// 要创建的文件系统的访问方式。 + /// 要创建的文件系统的文件系统流。 + /// 要创建的文件系统的最大文件数量。 + /// 要创建的文件系统的最大块数据数量。 + /// 创建的文件系统。 + public static FileSystem Create(string fullPath, FileSystemAccess access, FileSystemStream stream, int maxFileCount, int maxBlockCount) + { + if (maxFileCount <= 0) + { + throw new GameFrameworkException("Max file count is invalid."); + } + + if (maxBlockCount <= 0) + { + throw new GameFrameworkException("Max block count is invalid."); + } + + if (maxFileCount > maxBlockCount) + { + throw new GameFrameworkException("Max file count can not larger than max block count."); + } + + FileSystem fileSystem = new FileSystem(fullPath, access, stream); + fileSystem.m_HeaderData = new HeaderData(maxFileCount, maxBlockCount); + CalcOffsets(fileSystem); + Utility.Marshal.StructureToBytes(fileSystem.m_HeaderData, HeaderDataSize, s_CachedBytes); + + try + { + stream.Write(s_CachedBytes, 0, HeaderDataSize); + stream.SetLength(fileSystem.m_FileDataOffset); + return fileSystem; + } + catch + { + fileSystem.Shutdown(); + return null; + } + } + + /// + /// 加载文件系统。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 要加载的文件系统的文件系统流。 + /// 加载的文件系统。 + public static FileSystem Load(string fullPath, FileSystemAccess access, FileSystemStream stream) + { + FileSystem fileSystem = new FileSystem(fullPath, access, stream); + + stream.Read(s_CachedBytes, 0, HeaderDataSize); + fileSystem.m_HeaderData = Utility.Marshal.BytesToStructure(HeaderDataSize, s_CachedBytes); + if (!fileSystem.m_HeaderData.IsValid) + { + return null; + } + + CalcOffsets(fileSystem); + + if (fileSystem.m_BlockDatas.Capacity < fileSystem.m_HeaderData.BlockCount) + { + fileSystem.m_BlockDatas.Capacity = fileSystem.m_HeaderData.BlockCount; + } + + for (int i = 0; i < fileSystem.m_HeaderData.BlockCount; i++) + { + stream.Read(s_CachedBytes, 0, BlockDataSize); + BlockData blockData = Utility.Marshal.BytesToStructure(BlockDataSize, s_CachedBytes); + fileSystem.m_BlockDatas.Add(blockData); + } + + for (int i = 0; i < fileSystem.m_BlockDatas.Count; i++) + { + BlockData blockData = fileSystem.m_BlockDatas[i]; + if (blockData.Using) + { + StringData stringData = fileSystem.ReadStringData(blockData.StringIndex); + fileSystem.m_StringDatas.Add(blockData.StringIndex, stringData); + fileSystem.m_FileDatas.Add(stringData.GetString(fileSystem.m_HeaderData.GetEncryptBytes()), i); + } + else + { + fileSystem.m_FreeBlockIndexes.Add(blockData.Length, i); + } + } + + int index = 0; + foreach (KeyValuePair i in fileSystem.m_StringDatas) + { + while (index < i.Key) + { + fileSystem.m_FreeStringIndexes.Enqueue(index++); + } + + index++; + } + + return fileSystem; + } + + /// + /// 关闭并清理文件系统。 + /// + public void Shutdown() + { + m_Stream.Close(); + + m_FileDatas.Clear(); + m_BlockDatas.Clear(); + m_FreeBlockIndexes.Clear(); + m_StringDatas.Clear(); + m_FreeStringIndexes.Clear(); + m_FreeStringDatas.Clear(); + + m_BlockDataOffset = 0; + m_StringDataOffset = 0; + m_FileDataOffset = 0; + } + + /// + /// 获取文件信息。 + /// + /// 要获取文件信息的文件名称。 + /// 获取的文件信息。 + public FileInfo GetFileInfo(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + int blockIndex = 0; + if (!m_FileDatas.TryGetValue(name, out blockIndex)) + { + return default(FileInfo); + } + + BlockData blockData = m_BlockDatas[blockIndex]; + return new FileInfo(name, GetClusterOffset(blockData.ClusterIndex), blockData.Length); + } + + /// + /// 获取所有文件信息。 + /// + /// 获取的所有文件信息。 + public FileInfo[] GetAllFileInfos() + { + int index = 0; + FileInfo[] results = new FileInfo[m_FileDatas.Count]; + foreach (KeyValuePair fileData in m_FileDatas) + { + BlockData blockData = m_BlockDatas[fileData.Value]; + results[index++] = new FileInfo(fileData.Key, GetClusterOffset(blockData.ClusterIndex), blockData.Length); + } + + return results; + } + + /// + /// 获取所有文件信息。 + /// + /// 获取的所有文件信息。 + public void GetAllFileInfos(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair fileData in m_FileDatas) + { + BlockData blockData = m_BlockDatas[fileData.Value]; + results.Add(new FileInfo(fileData.Key, GetClusterOffset(blockData.ClusterIndex), blockData.Length)); + } + } + + /// + /// 检查是否存在指定文件。 + /// + /// 要检查的文件名称。 + /// 是否存在指定文件。 + public bool HasFile(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + return m_FileDatas.ContainsKey(name); + } + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + public byte[] ReadFile(string name) + { + if (m_Access != FileSystemAccess.Read && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not readable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + FileInfo fileInfo = GetFileInfo(name); + if (!fileInfo.IsValid) + { + return null; + } + + int length = fileInfo.Length; + byte[] buffer = new byte[length]; + if (length > 0) + { + m_Stream.Position = fileInfo.Offset; + m_Stream.Read(buffer, 0, length); + } + + return buffer; + } + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + /// 实际读取了多少字节。 + public int ReadFile(string name, byte[] buffer) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return ReadFile(name, buffer, 0, buffer.Length); + } + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + /// 存储读取文件内容的二进制流的起始位置。 + /// 实际读取了多少字节。 + public int ReadFile(string name, byte[] buffer, int startIndex) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return ReadFile(name, buffer, startIndex, buffer.Length - startIndex); + } + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + /// 存储读取文件内容的二进制流的起始位置。 + /// 存储读取文件内容的二进制流的长度。 + /// 实际读取了多少字节。 + public int ReadFile(string name, byte[] buffer, int startIndex, int length) + { + if (m_Access != FileSystemAccess.Read && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not readable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + if (startIndex < 0 || length < 0 || startIndex + length > buffer.Length) + { + throw new GameFrameworkException("Start index or length is invalid."); + } + + FileInfo fileInfo = GetFileInfo(name); + if (!fileInfo.IsValid) + { + return 0; + } + + m_Stream.Position = fileInfo.Offset; + if (length > fileInfo.Length) + { + length = fileInfo.Length; + } + + if (length > 0) + { + return m_Stream.Read(buffer, startIndex, length); + } + + return 0; + } + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + /// 实际读取了多少字节。 + public int ReadFile(string name, Stream stream) + { + if (m_Access != FileSystemAccess.Read && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not readable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (stream == null) + { + throw new GameFrameworkException("Stream is invalid."); + } + + if (!stream.CanWrite) + { + throw new GameFrameworkException("Stream is not writable."); + } + + FileInfo fileInfo = GetFileInfo(name); + if (!fileInfo.IsValid) + { + return 0; + } + + int length = fileInfo.Length; + if (length > 0) + { + m_Stream.Position = fileInfo.Offset; + return m_Stream.Read(stream, length); + } + + return 0; + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的长度。 + /// 存储读取文件片段内容的二进制流。 + public byte[] ReadFileSegment(string name, int length) + { + return ReadFileSegment(name, 0, length); + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 要读取片段的长度。 + /// 存储读取文件片段内容的二进制流。 + public byte[] ReadFileSegment(string name, int offset, int length) + { + if (m_Access != FileSystemAccess.Read && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not readable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (offset < 0) + { + throw new GameFrameworkException("Index is invalid."); + } + + if (length < 0) + { + throw new GameFrameworkException("Length is invalid."); + } + + FileInfo fileInfo = GetFileInfo(name); + if (!fileInfo.IsValid) + { + return null; + } + + if (offset > fileInfo.Length) + { + offset = fileInfo.Length; + } + + int leftLength = fileInfo.Length - offset; + if (length > leftLength) + { + length = leftLength; + } + + byte[] buffer = new byte[length]; + if (length > 0) + { + m_Stream.Position = fileInfo.Offset + offset; + m_Stream.Read(buffer, 0, length); + } + + return buffer; + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 存储读取文件片段内容的二进制流。 + /// 实际读取了多少字节。 + public int ReadFileSegment(string name, byte[] buffer) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return ReadFileSegment(name, 0, buffer, 0, buffer.Length); + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 存储读取文件片段内容的二进制流。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + public int ReadFileSegment(string name, byte[] buffer, int length) + { + return ReadFileSegment(name, 0, buffer, 0, length); + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 存储读取文件片段内容的二进制流。 + /// 存储读取文件片段内容的二进制流的起始位置。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + public int ReadFileSegment(string name, byte[] buffer, int startIndex, int length) + { + return ReadFileSegment(name, 0, buffer, startIndex, length); + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 存储读取文件片段内容的二进制流。 + /// 实际读取了多少字节。 + public int ReadFileSegment(string name, int offset, byte[] buffer) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return ReadFileSegment(name, offset, buffer, 0, buffer.Length); + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 存储读取文件片段内容的二进制流。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + public int ReadFileSegment(string name, int offset, byte[] buffer, int length) + { + return ReadFileSegment(name, offset, buffer, 0, length); + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 存储读取文件片段内容的二进制流。 + /// 存储读取文件片段内容的二进制流的起始位置。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + public int ReadFileSegment(string name, int offset, byte[] buffer, int startIndex, int length) + { + if (m_Access != FileSystemAccess.Read && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not readable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (offset < 0) + { + throw new GameFrameworkException("Index is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + if (startIndex < 0 || length < 0 || startIndex + length > buffer.Length) + { + throw new GameFrameworkException("Start index or length is invalid."); + } + + FileInfo fileInfo = GetFileInfo(name); + if (!fileInfo.IsValid) + { + return 0; + } + + if (offset > fileInfo.Length) + { + offset = fileInfo.Length; + } + + int leftLength = fileInfo.Length - offset; + if (length > leftLength) + { + length = leftLength; + } + + if (length > 0) + { + m_Stream.Position = fileInfo.Offset + offset; + return m_Stream.Read(buffer, startIndex, length); + } + + return 0; + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 存储读取文件片段内容的二进制流。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + public int ReadFileSegment(string name, Stream stream, int length) + { + return ReadFileSegment(name, 0, stream, length); + } + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 存储读取文件片段内容的二进制流。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + public int ReadFileSegment(string name, int offset, Stream stream, int length) + { + if (m_Access != FileSystemAccess.Read && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not readable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (offset < 0) + { + throw new GameFrameworkException("Index is invalid."); + } + + if (stream == null) + { + throw new GameFrameworkException("Stream is invalid."); + } + + if (!stream.CanWrite) + { + throw new GameFrameworkException("Stream is not writable."); + } + + if (length < 0) + { + throw new GameFrameworkException("Length is invalid."); + } + + FileInfo fileInfo = GetFileInfo(name); + if (!fileInfo.IsValid) + { + return 0; + } + + if (offset > fileInfo.Length) + { + offset = fileInfo.Length; + } + + int leftLength = fileInfo.Length - offset; + if (length > leftLength) + { + length = leftLength; + } + + if (length > 0) + { + m_Stream.Position = fileInfo.Offset + offset; + return m_Stream.Read(stream, length); + } + + return 0; + } + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的二进制流。 + /// 是否写入指定文件成功。 + public bool WriteFile(string name, byte[] buffer) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return WriteFile(name, buffer, 0, buffer.Length); + } + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的二进制流。 + /// 存储写入文件内容的二进制流的起始位置。 + /// 是否写入指定文件成功。 + public bool WriteFile(string name, byte[] buffer, int startIndex) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return WriteFile(name, buffer, startIndex, buffer.Length - startIndex); + } + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的二进制流。 + /// 存储写入文件内容的二进制流的起始位置。 + /// 存储写入文件内容的二进制流的长度。 + /// 是否写入指定文件成功。 + public bool WriteFile(string name, byte[] buffer, int startIndex, int length) + { + if (m_Access != FileSystemAccess.Write && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not writable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (name.Length > byte.MaxValue) + { + throw new GameFrameworkException(Utility.Text.Format("Name '{0}' is too long.", name)); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + if (startIndex < 0 || length < 0 || startIndex + length > buffer.Length) + { + throw new GameFrameworkException("Start index or length is invalid."); + } + + bool hasFile = false; + int oldBlockIndex = -1; + if (m_FileDatas.TryGetValue(name, out oldBlockIndex)) + { + hasFile = true; + } + + if (!hasFile && m_FileDatas.Count >= m_HeaderData.MaxFileCount) + { + return false; + } + + int blockIndex = AllocBlock(length); + if (blockIndex < 0) + { + return false; + } + + if (length > 0) + { + m_Stream.Position = GetClusterOffset(m_BlockDatas[blockIndex].ClusterIndex); + m_Stream.Write(buffer, startIndex, length); + } + + ProcessWriteFile(name, hasFile, oldBlockIndex, blockIndex, length); + m_Stream.Flush(); + return true; + } + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的二进制流。 + /// 是否写入指定文件成功。 + public bool WriteFile(string name, Stream stream) + { + if (m_Access != FileSystemAccess.Write && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not writable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (name.Length > byte.MaxValue) + { + throw new GameFrameworkException(Utility.Text.Format("Name '{0}' is too long.", name)); + } + + if (stream == null) + { + throw new GameFrameworkException("Stream is invalid."); + } + + if (!stream.CanRead) + { + throw new GameFrameworkException("Stream is not readable."); + } + + bool hasFile = false; + int oldBlockIndex = -1; + if (m_FileDatas.TryGetValue(name, out oldBlockIndex)) + { + hasFile = true; + } + + if (!hasFile && m_FileDatas.Count >= m_HeaderData.MaxFileCount) + { + return false; + } + + int length = (int)(stream.Length - stream.Position); + int blockIndex = AllocBlock(length); + if (blockIndex < 0) + { + return false; + } + + if (length > 0) + { + m_Stream.Position = GetClusterOffset(m_BlockDatas[blockIndex].ClusterIndex); + m_Stream.Write(stream, length); + } + + ProcessWriteFile(name, hasFile, oldBlockIndex, blockIndex, length); + m_Stream.Flush(); + return true; + } + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的文件路径。 + /// 是否写入指定文件成功。 + public bool WriteFile(string name, string filePath) + { + if (string.IsNullOrEmpty(filePath)) + { + throw new GameFrameworkException("File path is invalid"); + } + + if (!File.Exists(filePath)) + { + return false; + } + + using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return WriteFile(name, fileStream); + } + } + + /// + /// 将指定文件另存为物理文件。 + /// + /// 要另存为的文件名称。 + /// 存储写入文件内容的文件路径。 + /// 是否将指定文件另存为物理文件成功。 + public bool SaveAsFile(string name, string filePath) + { + if (m_Access != FileSystemAccess.Read && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not readable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (string.IsNullOrEmpty(filePath)) + { + throw new GameFrameworkException("File path is invalid"); + } + + FileInfo fileInfo = GetFileInfo(name); + if (!fileInfo.IsValid) + { + return false; + } + + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + + string directory = Path.GetDirectoryName(filePath); + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + int length = fileInfo.Length; + if (length > 0) + { + m_Stream.Position = fileInfo.Offset; + return m_Stream.Read(fileStream, length) == length; + } + + return true; + } + } + + /// + /// 重命名指定文件。 + /// + /// 要重命名的文件名称。 + /// 重命名后的文件名称。 + /// 是否重命名指定文件成功。 + public bool RenameFile(string oldName, string newName) + { + if (m_Access != FileSystemAccess.Write && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not writable."); + } + + if (string.IsNullOrEmpty(oldName)) + { + throw new GameFrameworkException("Old name is invalid."); + } + + if (string.IsNullOrEmpty(newName)) + { + throw new GameFrameworkException("New name is invalid."); + } + + if (newName.Length > byte.MaxValue) + { + throw new GameFrameworkException(Utility.Text.Format("New name '{0}' is too long.", newName)); + } + + if (oldName == newName) + { + return true; + } + + if (m_FileDatas.ContainsKey(newName)) + { + return false; + } + + int blockIndex = 0; + if (!m_FileDatas.TryGetValue(oldName, out blockIndex)) + { + return false; + } + + int stringIndex = m_BlockDatas[blockIndex].StringIndex; + StringData stringData = m_StringDatas[stringIndex].SetString(newName, m_HeaderData.GetEncryptBytes()); + m_StringDatas[stringIndex] = stringData; + WriteStringData(stringIndex, stringData); + m_FileDatas.Add(newName, blockIndex); + m_FileDatas.Remove(oldName); + m_Stream.Flush(); + return true; + } + + /// + /// 删除指定文件。 + /// + /// 要删除的文件名称。 + /// 是否删除指定文件成功。 + public bool DeleteFile(string name) + { + if (m_Access != FileSystemAccess.Write && m_Access != FileSystemAccess.ReadWrite) + { + throw new GameFrameworkException("File system is not writable."); + } + + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + int blockIndex = 0; + if (!m_FileDatas.TryGetValue(name, out blockIndex)) + { + return false; + } + + m_FileDatas.Remove(name); + + BlockData blockData = m_BlockDatas[blockIndex]; + int stringIndex = blockData.StringIndex; + StringData stringData = m_StringDatas[stringIndex].Clear(); + m_FreeStringIndexes.Enqueue(stringIndex); + m_FreeStringDatas.Enqueue(stringData); + m_StringDatas.Remove(stringIndex); + WriteStringData(stringIndex, stringData); + + blockData = blockData.Free(); + m_BlockDatas[blockIndex] = blockData; + if (!TryCombineFreeBlocks(blockIndex)) + { + m_FreeBlockIndexes.Add(blockData.Length, blockIndex); + WriteBlockData(blockIndex); + } + + m_Stream.Flush(); + return true; + } + + private void ProcessWriteFile(string name, bool hasFile, int oldBlockIndex, int blockIndex, int length) + { + BlockData blockData = m_BlockDatas[blockIndex]; + if (hasFile) + { + BlockData oldBlockData = m_BlockDatas[oldBlockIndex]; + blockData = new BlockData(oldBlockData.StringIndex, blockData.ClusterIndex, length); + m_BlockDatas[blockIndex] = blockData; + WriteBlockData(blockIndex); + + oldBlockData = oldBlockData.Free(); + m_BlockDatas[oldBlockIndex] = oldBlockData; + if (!TryCombineFreeBlocks(oldBlockIndex)) + { + m_FreeBlockIndexes.Add(oldBlockData.Length, oldBlockIndex); + WriteBlockData(oldBlockIndex); + } + } + else + { + int stringIndex = AllocString(name); + blockData = new BlockData(stringIndex, blockData.ClusterIndex, length); + m_BlockDatas[blockIndex] = blockData; + WriteBlockData(blockIndex); + } + + if (hasFile) + { + m_FileDatas[name] = blockIndex; + } + else + { + m_FileDatas.Add(name, blockIndex); + } + } + + private bool TryCombineFreeBlocks(int freeBlockIndex) + { + BlockData freeBlockData = m_BlockDatas[freeBlockIndex]; + if (freeBlockData.Length <= 0) + { + return false; + } + + int previousFreeBlockIndex = -1; + int nextFreeBlockIndex = -1; + int nextBlockDataClusterIndex = freeBlockData.ClusterIndex + GetUpBoundClusterCount(freeBlockData.Length); + foreach (KeyValuePair> blockIndexes in m_FreeBlockIndexes) + { + if (blockIndexes.Key <= 0) + { + continue; + } + + int blockDataClusterCount = GetUpBoundClusterCount(blockIndexes.Key); + foreach (int blockIndex in blockIndexes.Value) + { + BlockData blockData = m_BlockDatas[blockIndex]; + if (blockData.ClusterIndex + blockDataClusterCount == freeBlockData.ClusterIndex) + { + previousFreeBlockIndex = blockIndex; + } + else if (blockData.ClusterIndex == nextBlockDataClusterIndex) + { + nextFreeBlockIndex = blockIndex; + } + } + } + + if (previousFreeBlockIndex < 0 && nextFreeBlockIndex < 0) + { + return false; + } + + m_FreeBlockIndexes.Remove(freeBlockData.Length, freeBlockIndex); + if (previousFreeBlockIndex >= 0) + { + BlockData previousFreeBlockData = m_BlockDatas[previousFreeBlockIndex]; + m_FreeBlockIndexes.Remove(previousFreeBlockData.Length, previousFreeBlockIndex); + freeBlockData = new BlockData(previousFreeBlockData.ClusterIndex, previousFreeBlockData.Length + freeBlockData.Length); + m_BlockDatas[previousFreeBlockIndex] = BlockData.Empty; + m_FreeBlockIndexes.Add(0, previousFreeBlockIndex); + WriteBlockData(previousFreeBlockIndex); + } + + if (nextFreeBlockIndex >= 0) + { + BlockData nextFreeBlockData = m_BlockDatas[nextFreeBlockIndex]; + m_FreeBlockIndexes.Remove(nextFreeBlockData.Length, nextFreeBlockIndex); + freeBlockData = new BlockData(freeBlockData.ClusterIndex, freeBlockData.Length + nextFreeBlockData.Length); + m_BlockDatas[nextFreeBlockIndex] = BlockData.Empty; + m_FreeBlockIndexes.Add(0, nextFreeBlockIndex); + WriteBlockData(nextFreeBlockIndex); + } + + m_BlockDatas[freeBlockIndex] = freeBlockData; + m_FreeBlockIndexes.Add(freeBlockData.Length, freeBlockIndex); + WriteBlockData(freeBlockIndex); + return true; + } + + private int GetEmptyBlockIndex() + { + GameFrameworkLinkedListRange lengthRange = default(GameFrameworkLinkedListRange); + if (m_FreeBlockIndexes.TryGetValue(0, out lengthRange)) + { + int blockIndex = lengthRange.First.Value; + m_FreeBlockIndexes.Remove(0, blockIndex); + return blockIndex; + } + + if (m_BlockDatas.Count < m_HeaderData.MaxBlockCount) + { + int blockIndex = m_BlockDatas.Count; + m_BlockDatas.Add(BlockData.Empty); + WriteHeaderData(); + return blockIndex; + } + + return -1; + } + + private int AllocBlock(int length) + { + if (length <= 0) + { + return GetEmptyBlockIndex(); + } + + length = (int)GetUpBoundClusterOffset(length); + + int lengthFound = -1; + GameFrameworkLinkedListRange lengthRange = default(GameFrameworkLinkedListRange); + foreach (KeyValuePair> i in m_FreeBlockIndexes) + { + if (i.Key < length) + { + continue; + } + + if (lengthFound >= 0 && lengthFound < i.Key) + { + continue; + } + + lengthFound = i.Key; + lengthRange = i.Value; + } + + if (lengthFound >= 0) + { + if (lengthFound > length && m_BlockDatas.Count >= m_HeaderData.MaxBlockCount) + { + return -1; + } + + int blockIndex = lengthRange.First.Value; + m_FreeBlockIndexes.Remove(lengthFound, blockIndex); + if (lengthFound > length) + { + BlockData blockData = m_BlockDatas[blockIndex]; + m_BlockDatas[blockIndex] = new BlockData(blockData.ClusterIndex, length); + WriteBlockData(blockIndex); + + int deltaLength = lengthFound - length; + int anotherBlockIndex = GetEmptyBlockIndex(); + m_BlockDatas[anotherBlockIndex] = new BlockData(blockData.ClusterIndex + GetUpBoundClusterCount(length), deltaLength); + m_FreeBlockIndexes.Add(deltaLength, anotherBlockIndex); + WriteBlockData(anotherBlockIndex); + } + + return blockIndex; + } + else + { + int blockIndex = GetEmptyBlockIndex(); + if (blockIndex < 0) + { + return -1; + } + + long fileLength = m_Stream.Length; + try + { + m_Stream.SetLength(fileLength + length); + } + catch + { + return -1; + } + + m_BlockDatas[blockIndex] = new BlockData(GetUpBoundClusterCount(fileLength), length); + WriteBlockData(blockIndex); + return blockIndex; + } + } + + private int AllocString(string value) + { + int stringIndex = -1; + StringData stringData = default(StringData); + + if (m_FreeStringIndexes.Count > 0) + { + stringIndex = m_FreeStringIndexes.Dequeue(); + } + else + { + stringIndex = m_StringDatas.Count; + } + + if (m_FreeStringDatas.Count > 0) + { + stringData = m_FreeStringDatas.Dequeue(); + } + else + { + byte[] bytes = new byte[byte.MaxValue]; + Utility.Random.GetRandomBytes(bytes); + stringData = new StringData(0, bytes); + } + + stringData = stringData.SetString(value, m_HeaderData.GetEncryptBytes()); + m_StringDatas.Add(stringIndex, stringData); + WriteStringData(stringIndex, stringData); + return stringIndex; + } + + private void WriteHeaderData() + { + m_HeaderData = m_HeaderData.SetBlockCount(m_BlockDatas.Count); + Utility.Marshal.StructureToBytes(m_HeaderData, HeaderDataSize, s_CachedBytes); + m_Stream.Position = 0L; + m_Stream.Write(s_CachedBytes, 0, HeaderDataSize); + } + + private void WriteBlockData(int blockIndex) + { + Utility.Marshal.StructureToBytes(m_BlockDatas[blockIndex], BlockDataSize, s_CachedBytes); + m_Stream.Position = m_BlockDataOffset + BlockDataSize * blockIndex; + m_Stream.Write(s_CachedBytes, 0, BlockDataSize); + } + + private StringData ReadStringData(int stringIndex) + { + m_Stream.Position = m_StringDataOffset + StringDataSize * stringIndex; + m_Stream.Read(s_CachedBytes, 0, StringDataSize); + return Utility.Marshal.BytesToStructure(StringDataSize, s_CachedBytes); + } + + private void WriteStringData(int stringIndex, StringData stringData) + { + Utility.Marshal.StructureToBytes(stringData, StringDataSize, s_CachedBytes); + m_Stream.Position = m_StringDataOffset + StringDataSize * stringIndex; + m_Stream.Write(s_CachedBytes, 0, StringDataSize); + } + + private static void CalcOffsets(FileSystem fileSystem) + { + fileSystem.m_BlockDataOffset = HeaderDataSize; + fileSystem.m_StringDataOffset = fileSystem.m_BlockDataOffset + BlockDataSize * fileSystem.m_HeaderData.MaxBlockCount; + fileSystem.m_FileDataOffset = (int)GetUpBoundClusterOffset(fileSystem.m_StringDataOffset + StringDataSize * fileSystem.m_HeaderData.MaxFileCount); + } + + private static long GetUpBoundClusterOffset(long offset) + { + return (offset - 1L + ClusterSize) / ClusterSize * ClusterSize; + } + + private static int GetUpBoundClusterCount(long length) + { + return (int)((length - 1L + ClusterSize) / ClusterSize); + } + + private static long GetClusterOffset(int clusterIndex) + { + return (long)ClusterSize * clusterIndex; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.cs.meta new file mode 100644 index 0000000..69e2395 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: adee24668eb76c648a130884359b6db7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemAccess.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemAccess.cs new file mode 100644 index 0000000..b0bc1be --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemAccess.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.FileSystem +{ + /// + /// 文件系统访问方式。 + /// + [Flags] + public enum FileSystemAccess : byte + { + /// + /// 未指定。 + /// + Unspecified = 0, + + /// + /// 只可读。 + /// + Read = 1, + + /// + /// 只可写。 + /// + Write = 2, + + /// + /// 可读写。 + /// + ReadWrite = 3 + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemAccess.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemAccess.cs.meta new file mode 100644 index 0000000..02b56f8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemAccess.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe041668e95005446a79c11fa344a1a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemManager.cs new file mode 100644 index 0000000..81a751d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemManager.cs @@ -0,0 +1,283 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.FileSystem +{ + /// + /// 文件系统管理器。 + /// + internal sealed class FileSystemManager : GameFrameworkModule, IFileSystemManager + { + private readonly Dictionary m_FileSystems; + + private IFileSystemHelper m_FileSystemHelper; + + /// + /// 初始化文件系统管理器的新实例。 + /// + public FileSystemManager() + { + m_FileSystems = new Dictionary(StringComparer.Ordinal); + m_FileSystemHelper = null; + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return 4; + } + } + + /// + /// 获取文件系统数量。 + /// + public int Count + { + get + { + return m_FileSystems.Count; + } + } + + /// + /// 文件系统管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理文件系统管理器。 + /// + internal override void Shutdown() + { + while (m_FileSystems.Count > 0) + { + foreach (KeyValuePair fileSystem in m_FileSystems) + { + DestroyFileSystem(fileSystem.Value, false); + break; + } + } + } + + /// + /// 设置文件系统辅助器。 + /// + /// 文件系统辅助器。 + public void SetFileSystemHelper(IFileSystemHelper fileSystemHelper) + { + if (fileSystemHelper == null) + { + throw new GameFrameworkException("File system helper is invalid."); + } + + m_FileSystemHelper = fileSystemHelper; + } + + /// + /// 检查是否存在文件系统。 + /// + /// 要检查的文件系统的完整路径。 + /// 是否存在文件系统。 + public bool HasFileSystem(string fullPath) + { + if (string.IsNullOrEmpty(fullPath)) + { + throw new GameFrameworkException("Full path is invalid."); + } + + return m_FileSystems.ContainsKey(Utility.Path.GetRegularPath(fullPath)); + } + + /// + /// 获取文件系统。 + /// + /// 要获取的文件系统的完整路径。 + /// 获取的文件系统。 + public IFileSystem GetFileSystem(string fullPath) + { + if (string.IsNullOrEmpty(fullPath)) + { + throw new GameFrameworkException("Full path is invalid."); + } + + FileSystem fileSystem = null; + if (m_FileSystems.TryGetValue(Utility.Path.GetRegularPath(fullPath), out fileSystem)) + { + return fileSystem; + } + + return null; + } + + /// + /// 创建文件系统。 + /// + /// 要创建的文件系统的完整路径。 + /// 要创建的文件系统的访问方式。 + /// 要创建的文件系统的最大文件数量。 + /// 要创建的文件系统的最大块数据数量。 + /// 创建的文件系统。 + public IFileSystem CreateFileSystem(string fullPath, FileSystemAccess access, int maxFileCount, int maxBlockCount) + { + if (m_FileSystemHelper == null) + { + throw new GameFrameworkException("File system helper is invalid."); + } + + if (string.IsNullOrEmpty(fullPath)) + { + throw new GameFrameworkException("Full path is invalid."); + } + + if (access == FileSystemAccess.Unspecified) + { + throw new GameFrameworkException("Access is invalid."); + } + + if (access == FileSystemAccess.Read) + { + throw new GameFrameworkException("Access read is invalid."); + } + + fullPath = Utility.Path.GetRegularPath(fullPath); + if (m_FileSystems.ContainsKey(fullPath)) + { + throw new GameFrameworkException(Utility.Text.Format("File system '{0}' is already exist.", fullPath)); + } + + FileSystemStream fileSystemStream = m_FileSystemHelper.CreateFileSystemStream(fullPath, access, true); + if (fileSystemStream == null) + { + throw new GameFrameworkException(Utility.Text.Format("Create file system stream for '{0}' failure.", fullPath)); + } + + FileSystem fileSystem = FileSystem.Create(fullPath, access, fileSystemStream, maxFileCount, maxBlockCount); + if (fileSystem == null) + { + throw new GameFrameworkException(Utility.Text.Format("Create file system '{0}' failure.", fullPath)); + } + + m_FileSystems.Add(fullPath, fileSystem); + return fileSystem; + } + + /// + /// 加载文件系统。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 加载的文件系统。 + public IFileSystem LoadFileSystem(string fullPath, FileSystemAccess access) + { + if (m_FileSystemHelper == null) + { + throw new GameFrameworkException("File system helper is invalid."); + } + + if (string.IsNullOrEmpty(fullPath)) + { + throw new GameFrameworkException("Full path is invalid."); + } + + if (access == FileSystemAccess.Unspecified) + { + throw new GameFrameworkException("Access is invalid."); + } + + fullPath = Utility.Path.GetRegularPath(fullPath); + if (m_FileSystems.ContainsKey(fullPath)) + { + throw new GameFrameworkException(Utility.Text.Format("File system '{0}' is already exist.", fullPath)); + } + + FileSystemStream fileSystemStream = m_FileSystemHelper.CreateFileSystemStream(fullPath, access, false); + if (fileSystemStream == null) + { + throw new GameFrameworkException(Utility.Text.Format("Create file system stream for '{0}' failure.", fullPath)); + } + + FileSystem fileSystem = FileSystem.Load(fullPath, access, fileSystemStream); + if (fileSystem == null) + { + fileSystemStream.Close(); + throw new GameFrameworkException(Utility.Text.Format("Load file system '{0}' failure.", fullPath)); + } + + m_FileSystems.Add(fullPath, fileSystem); + return fileSystem; + } + + /// + /// 销毁文件系统。 + /// + /// 要销毁的文件系统。 + /// 是否删除文件系统对应的物理文件。 + public void DestroyFileSystem(IFileSystem fileSystem, bool deletePhysicalFile) + { + if (fileSystem == null) + { + throw new GameFrameworkException("File system is invalid."); + } + + string fullPath = fileSystem.FullPath; + ((FileSystem)fileSystem).Shutdown(); + m_FileSystems.Remove(fullPath); + + if (deletePhysicalFile && File.Exists(fullPath)) + { + File.Delete(fullPath); + } + } + + /// + /// 获取所有文件系统集合。 + /// + /// 获取的所有文件系统集合。 + public IFileSystem[] GetAllFileSystems() + { + int index = 0; + IFileSystem[] results = new IFileSystem[m_FileSystems.Count]; + foreach (KeyValuePair fileSystem in m_FileSystems) + { + results[index++] = fileSystem.Value; + } + + return results; + } + + /// + /// 获取所有文件系统集合。 + /// + /// 获取的所有文件系统集合。 + public void GetAllFileSystems(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair fileSystem in m_FileSystems) + { + results.Add(fileSystem.Value); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemManager.cs.meta new file mode 100644 index 0000000..6d788b9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 847cf72ef4e839c44963a669560ae00d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemStream.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemStream.cs new file mode 100644 index 0000000..f0a1846 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemStream.cs @@ -0,0 +1,135 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.IO; + +namespace GameFramework.FileSystem +{ + /// + /// 文件系统流。 + /// + public abstract class FileSystemStream + { + /// + /// 缓存二进制流的长度。 + /// + protected const int CachedBytesLength = 0x1000; + + /// + /// 缓存二进制流。 + /// + protected static readonly byte[] s_CachedBytes = new byte[CachedBytesLength]; + + /// + /// 获取或设置文件系统流位置。 + /// + public abstract long Position + { + get; + set; + } + + /// + /// 获取文件系统流长度。 + /// + public abstract long Length + { + get; + } + + /// + /// 设置文件系统流长度。 + /// + /// 要设置的文件系统流的长度。 + public abstract void SetLength(long length); + + /// + /// 定位文件系统流位置。 + /// + /// 要定位的文件系统流位置的偏移。 + /// 要定位的文件系统流位置的方式。 + public abstract void Seek(long offset, SeekOrigin origin); + + /// + /// 从文件系统流中读取一个字节。 + /// + /// 读取的字节,若已经到达文件结尾,则返回 -1。 + public abstract int ReadByte(); + + /// + /// 从文件系统流中读取二进制流。 + /// + /// 存储读取文件内容的二进制流。 + /// 存储读取文件内容的二进制流的起始位置。 + /// 存储读取文件内容的二进制流的长度。 + /// 实际读取了多少字节。 + public abstract int Read(byte[] buffer, int startIndex, int length); + + /// + /// 从文件系统流中读取二进制流。 + /// + /// 存储读取文件内容的二进制流。 + /// 存储读取文件内容的二进制流的长度。 + /// 实际读取了多少字节。 + public int Read(Stream stream, int length) + { + int bytesRead = 0; + int bytesLeft = length; + while ((bytesRead = Read(s_CachedBytes, 0, bytesLeft < CachedBytesLength ? bytesLeft : CachedBytesLength)) > 0) + { + bytesLeft -= bytesRead; + stream.Write(s_CachedBytes, 0, bytesRead); + } + + Array.Clear(s_CachedBytes, 0, CachedBytesLength); + return length - bytesLeft; + } + + /// + /// 向文件系统流中写入一个字节。 + /// + /// 要写入的字节。 + public abstract void WriteByte(byte value); + + /// + /// 向文件系统流中写入二进制流。 + /// + /// 存储写入文件内容的二进制流。 + /// 存储写入文件内容的二进制流的起始位置。 + /// 存储写入文件内容的二进制流的长度。 + public abstract void Write(byte[] buffer, int startIndex, int length); + + /// + /// 向文件系统流中写入二进制流。 + /// + /// 存储写入文件内容的二进制流。 + /// 存储写入文件内容的二进制流的长度。 + public void Write(Stream stream, int length) + { + int bytesRead = 0; + int bytesLeft = length; + while ((bytesRead = stream.Read(s_CachedBytes, 0, bytesLeft < CachedBytesLength ? bytesLeft : CachedBytesLength)) > 0) + { + bytesLeft -= bytesRead; + Write(s_CachedBytes, 0, bytesRead); + } + + Array.Clear(s_CachedBytes, 0, CachedBytesLength); + } + + /// + /// 将文件系统流立刻更新到存储介质中。 + /// + public abstract void Flush(); + + /// + /// 关闭文件系统流。 + /// + public abstract void Close(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemStream.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemStream.cs.meta new file mode 100644 index 0000000..44436f1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/FileSystemStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 29982ed701ce57b409a664688940a07b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystem.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystem.cs new file mode 100644 index 0000000..1b7944e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystem.cs @@ -0,0 +1,277 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.FileSystem +{ + /// + /// 文件系统接口。 + /// + public interface IFileSystem + { + /// + /// 获取文件系统完整路径。 + /// + string FullPath + { + get; + } + + /// + /// 获取文件系统访问方式。 + /// + FileSystemAccess Access + { + get; + } + + /// + /// 获取文件数量。 + /// + int FileCount + { + get; + } + + /// + /// 获取最大文件数量。 + /// + int MaxFileCount + { + get; + } + + /// + /// 获取文件信息。 + /// + /// 要获取文件信息的文件名称。 + /// 获取的文件信息。 + FileInfo GetFileInfo(string name); + + /// + /// 获取所有文件信息。 + /// + /// 获取的所有文件信息。 + FileInfo[] GetAllFileInfos(); + + /// + /// 获取所有文件信息。 + /// + /// 获取的所有文件信息。 + void GetAllFileInfos(List results); + + /// + /// 检查是否存在指定文件。 + /// + /// 要检查的文件名称。 + /// 是否存在指定文件。 + bool HasFile(string name); + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + byte[] ReadFile(string name); + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + /// 实际读取了多少字节。 + int ReadFile(string name, byte[] buffer); + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + /// 存储读取文件内容的二进制流的起始位置。 + /// 实际读取了多少字节。 + int ReadFile(string name, byte[] buffer, int startIndex); + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + /// 存储读取文件内容的二进制流的起始位置。 + /// 存储读取文件内容的二进制流的长度。 + /// 实际读取了多少字节。 + int ReadFile(string name, byte[] buffer, int startIndex, int length); + + /// + /// 读取指定文件。 + /// + /// 要读取的文件名称。 + /// 存储读取文件内容的二进制流。 + /// 实际读取了多少字节。 + int ReadFile(string name, Stream stream); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的长度。 + /// 存储读取文件片段内容的二进制流。 + byte[] ReadFileSegment(string name, int length); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 要读取片段的长度。 + /// 存储读取文件片段内容的二进制流。 + byte[] ReadFileSegment(string name, int offset, int length); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 存储读取文件片段内容的二进制流。 + /// 实际读取了多少字节。 + int ReadFileSegment(string name, byte[] buffer); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 存储读取文件片段内容的二进制流。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + int ReadFileSegment(string name, byte[] buffer, int length); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 存储读取文件片段内容的二进制流。 + /// 存储读取文件片段内容的二进制流的起始位置。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + int ReadFileSegment(string name, byte[] buffer, int startIndex, int length); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 存储读取文件片段内容的二进制流。 + /// 实际读取了多少字节。 + int ReadFileSegment(string name, int offset, byte[] buffer); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 存储读取文件片段内容的二进制流。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + int ReadFileSegment(string name, int offset, byte[] buffer, int length); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 存储读取文件片段内容的二进制流。 + /// 存储读取文件片段内容的二进制流的起始位置。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + int ReadFileSegment(string name, int offset, byte[] buffer, int startIndex, int length); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 存储读取文件片段内容的二进制流。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + int ReadFileSegment(string name, Stream stream, int length); + + /// + /// 读取指定文件的指定片段。 + /// + /// 要读取片段的文件名称。 + /// 要读取片段的偏移。 + /// 存储读取文件片段内容的二进制流。 + /// 要读取片段的长度。 + /// 实际读取了多少字节。 + int ReadFileSegment(string name, int offset, Stream stream, int length); + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的二进制流。 + /// 是否写入指定文件成功。 + bool WriteFile(string name, byte[] buffer); + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的二进制流。 + /// 存储写入文件内容的二进制流的起始位置。 + /// 是否写入指定文件成功。 + bool WriteFile(string name, byte[] buffer, int startIndex); + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的二进制流。 + /// 存储写入文件内容的二进制流的起始位置。 + /// 存储写入文件内容的二进制流的长度。 + /// 是否写入指定文件成功。 + bool WriteFile(string name, byte[] buffer, int startIndex, int length); + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的二进制流。 + /// 是否写入指定文件成功。 + bool WriteFile(string name, Stream stream); + + /// + /// 写入指定文件。 + /// + /// 要写入的文件名称。 + /// 存储写入文件内容的文件路径。 + /// 是否写入指定文件成功。 + bool WriteFile(string name, string filePath); + + /// + /// 将指定文件另存为物理文件。 + /// + /// 要另存为的文件名称。 + /// 存储写入文件内容的文件路径。 + /// 是否将指定文件另存为物理文件成功。 + bool SaveAsFile(string name, string filePath); + + /// + /// 重命名指定文件。 + /// + /// 要重命名的文件名称。 + /// 重命名后的文件名称。 + /// 是否重命名指定文件成功。 + bool RenameFile(string oldName, string newName); + + /// + /// 删除指定文件。 + /// + /// 要删除的文件名称。 + /// 是否删除指定文件成功。 + bool DeleteFile(string name); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystem.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystem.cs.meta new file mode 100644 index 0000000..82793ef --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8579bcaa59f35d141b05835ce0590b81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemHelper.cs new file mode 100644 index 0000000..546ee80 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemHelper.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.FileSystem +{ + /// + /// 文件系统辅助器接口。 + /// + public interface IFileSystemHelper + { + /// + /// 创建文件系统流。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 是否创建新的文件系统流。 + /// 创建的文件系统流。 + FileSystemStream CreateFileSystemStream(string fullPath, FileSystemAccess access, bool createNew); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemHelper.cs.meta new file mode 100644 index 0000000..2a60df2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2590f8fdb586a4c4688082efdcb6182c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemManager.cs new file mode 100644 index 0000000..866cbe0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemManager.cs @@ -0,0 +1,82 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.FileSystem +{ + /// + /// 文件系统管理器。 + /// + public interface IFileSystemManager + { + /// + /// 获取文件系统数量。 + /// + int Count + { + get; + } + + /// + /// 设置文件系统辅助器。 + /// + /// 文件系统辅助器。 + void SetFileSystemHelper(IFileSystemHelper fileSystemHelper); + + /// + /// 检查是否存在文件系统。 + /// + /// 要检查的文件系统的完整路径。 + /// 是否存在文件系统。 + bool HasFileSystem(string fullPath); + + /// + /// 获取文件系统。 + /// + /// 要获取的文件系统的完整路径。 + /// 获取的文件系统。 + IFileSystem GetFileSystem(string fullPath); + + /// + /// 创建文件系统。 + /// + /// 要创建的文件系统的完整路径。 + /// 要创建的文件系统的访问方式。 + /// 要创建的文件系统的最大文件数量。 + /// 要创建的文件系统的最大块数据数量。 + /// 创建的文件系统。 + IFileSystem CreateFileSystem(string fullPath, FileSystemAccess access, int maxFileCount, int maxBlockCount); + + /// + /// 加载文件系统。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 加载的文件系统。 + IFileSystem LoadFileSystem(string fullPath, FileSystemAccess access); + + /// + /// 销毁文件系统。 + /// + /// 要销毁的文件系统。 + /// 是否删除文件系统对应的物理文件。 + void DestroyFileSystem(IFileSystem fileSystem, bool deletePhysicalFile); + + /// + /// 获取所有文件系统集合。 + /// + /// 获取的所有文件系统集合。 + IFileSystem[] GetAllFileSystems(); + + /// + /// 获取所有文件系统集合。 + /// + /// 获取的所有文件系统集合。 + void GetAllFileSystems(List results); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemManager.cs.meta new file mode 100644 index 0000000..a58b819 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/FileSystem/IFileSystemManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10ae1b26debca324b94218750fd78cf7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm.meta new file mode 100644 index 0000000..0ccacb6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0267b272dd3ee21439390ebec948002c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/Fsm.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/Fsm.cs new file mode 100644 index 0000000..a218e10 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/Fsm.cs @@ -0,0 +1,588 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Fsm +{ + /// + /// 有限状态机。 + /// + /// 有限状态机持有者类型。 + internal sealed class Fsm : FsmBase, IReference, IFsm where T : class + { + private T m_Owner; + private readonly Dictionary> m_States; + private Dictionary m_Datas; + private FsmState m_CurrentState; + private float m_CurrentStateTime; + private bool m_IsDestroyed; + + /// + /// 初始化有限状态机的新实例。 + /// + public Fsm() + { + m_Owner = null; + m_States = new Dictionary>(); + m_Datas = null; + m_CurrentState = null; + m_CurrentStateTime = 0f; + m_IsDestroyed = true; + } + + /// + /// 获取有限状态机持有者。 + /// + public T Owner + { + get + { + return m_Owner; + } + } + + /// + /// 获取有限状态机持有者类型。 + /// + public override Type OwnerType + { + get + { + return typeof(T); + } + } + + /// + /// 获取有限状态机中状态的数量。 + /// + public override int FsmStateCount + { + get + { + return m_States.Count; + } + } + + /// + /// 获取有限状态机是否正在运行。 + /// + public override bool IsRunning + { + get + { + return m_CurrentState != null; + } + } + + /// + /// 获取有限状态机是否被销毁。 + /// + public override bool IsDestroyed + { + get + { + return m_IsDestroyed; + } + } + + /// + /// 获取当前有限状态机状态。 + /// + public FsmState CurrentState + { + get + { + return m_CurrentState; + } + } + + /// + /// 获取当前有限状态机状态名称。 + /// + public override string CurrentStateName + { + get + { + return m_CurrentState != null ? m_CurrentState.GetType().FullName : null; + } + } + + /// + /// 获取当前有限状态机状态持续时间。 + /// + public override float CurrentStateTime + { + get + { + return m_CurrentStateTime; + } + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 创建的有限状态机。 + public static Fsm Create(string name, T owner, params FsmState[] states) + { + if (owner == null) + { + throw new GameFrameworkException("FSM owner is invalid."); + } + + if (states == null || states.Length < 1) + { + throw new GameFrameworkException("FSM states is invalid."); + } + + Fsm fsm = ReferencePool.Acquire>(); + fsm.Name = name; + fsm.m_Owner = owner; + fsm.m_IsDestroyed = false; + foreach (FsmState state in states) + { + if (state == null) + { + throw new GameFrameworkException("FSM states is invalid."); + } + + Type stateType = state.GetType(); + if (fsm.m_States.ContainsKey(stateType)) + { + throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' state '{1}' is already exist.", new TypeNamePair(typeof(T), name), stateType.FullName)); + } + + fsm.m_States.Add(stateType, state); + state.OnInit(fsm); + } + + return fsm; + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 创建的有限状态机。 + public static Fsm Create(string name, T owner, List> states) + { + if (owner == null) + { + throw new GameFrameworkException("FSM owner is invalid."); + } + + if (states == null || states.Count < 1) + { + throw new GameFrameworkException("FSM states is invalid."); + } + + Fsm fsm = ReferencePool.Acquire>(); + fsm.Name = name; + fsm.m_Owner = owner; + fsm.m_IsDestroyed = false; + foreach (FsmState state in states) + { + if (state == null) + { + throw new GameFrameworkException("FSM states is invalid."); + } + + Type stateType = state.GetType(); + if (fsm.m_States.ContainsKey(stateType)) + { + throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' state '{1}' is already exist.", new TypeNamePair(typeof(T), name), stateType.FullName)); + } + + fsm.m_States.Add(stateType, state); + state.OnInit(fsm); + } + + return fsm; + } + + /// + /// 清理有限状态机。 + /// + public void Clear() + { + if (m_CurrentState != null) + { + m_CurrentState.OnLeave(this, true); + } + + foreach (KeyValuePair> state in m_States) + { + state.Value.OnDestroy(this); + } + + Name = null; + m_Owner = null; + m_States.Clear(); + + if (m_Datas != null) + { + foreach (KeyValuePair data in m_Datas) + { + if (data.Value == null) + { + continue; + } + + ReferencePool.Release(data.Value); + } + + m_Datas.Clear(); + } + + m_CurrentState = null; + m_CurrentStateTime = 0f; + m_IsDestroyed = true; + } + + /// + /// 开始有限状态机。 + /// + /// 要开始的有限状态机状态类型。 + public void Start() where TState : FsmState + { + if (IsRunning) + { + throw new GameFrameworkException("FSM is running, can not start again."); + } + + FsmState state = GetState(); + if (state == null) + { + throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not start state '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), typeof(TState).FullName)); + } + + m_CurrentStateTime = 0f; + m_CurrentState = state; + m_CurrentState.OnEnter(this); + } + + /// + /// 开始有限状态机。 + /// + /// 要开始的有限状态机状态类型。 + public void Start(Type stateType) + { + if (IsRunning) + { + throw new GameFrameworkException("FSM is running, can not start again."); + } + + if (stateType == null) + { + throw new GameFrameworkException("State type is invalid."); + } + + if (!typeof(FsmState).IsAssignableFrom(stateType)) + { + throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName)); + } + + FsmState state = GetState(stateType); + if (state == null) + { + throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not start state '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), stateType.FullName)); + } + + m_CurrentStateTime = 0f; + m_CurrentState = state; + m_CurrentState.OnEnter(this); + } + + /// + /// 是否存在有限状态机状态。 + /// + /// 要检查的有限状态机状态类型。 + /// 是否存在有限状态机状态。 + public bool HasState() where TState : FsmState + { + return m_States.ContainsKey(typeof(TState)); + } + + /// + /// 是否存在有限状态机状态。 + /// + /// 要检查的有限状态机状态类型。 + /// 是否存在有限状态机状态。 + public bool HasState(Type stateType) + { + if (stateType == null) + { + throw new GameFrameworkException("State type is invalid."); + } + + if (!typeof(FsmState).IsAssignableFrom(stateType)) + { + throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName)); + } + + return m_States.ContainsKey(stateType); + } + + /// + /// 获取有限状态机状态。 + /// + /// 要获取的有限状态机状态类型。 + /// 要获取的有限状态机状态。 + public TState GetState() where TState : FsmState + { + FsmState state = null; + if (m_States.TryGetValue(typeof(TState), out state)) + { + return (TState)state; + } + + return null; + } + + /// + /// 获取有限状态机状态。 + /// + /// 要获取的有限状态机状态类型。 + /// 要获取的有限状态机状态。 + public FsmState GetState(Type stateType) + { + if (stateType == null) + { + throw new GameFrameworkException("State type is invalid."); + } + + if (!typeof(FsmState).IsAssignableFrom(stateType)) + { + throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName)); + } + + FsmState state = null; + if (m_States.TryGetValue(stateType, out state)) + { + return state; + } + + return null; + } + + /// + /// 获取有限状态机的所有状态。 + /// + /// 有限状态机的所有状态。 + public FsmState[] GetAllStates() + { + int index = 0; + FsmState[] results = new FsmState[m_States.Count]; + foreach (KeyValuePair> state in m_States) + { + results[index++] = state.Value; + } + + return results; + } + + /// + /// 获取有限状态机的所有状态。 + /// + /// 有限状态机的所有状态。 + public void GetAllStates(List> results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair> state in m_States) + { + results.Add(state.Value); + } + } + + /// + /// 是否存在有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 有限状态机数据是否存在。 + public bool HasData(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Data name is invalid."); + } + + if (m_Datas == null) + { + return false; + } + + return m_Datas.ContainsKey(name); + } + + /// + /// 获取有限状态机数据。 + /// + /// 要获取的有限状态机数据的类型。 + /// 有限状态机数据名称。 + /// 要获取的有限状态机数据。 + public TData GetData(string name) where TData : Variable + { + return (TData)GetData(name); + } + + /// + /// 获取有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 要获取的有限状态机数据。 + public Variable GetData(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Data name is invalid."); + } + + if (m_Datas == null) + { + return null; + } + + Variable data = null; + if (m_Datas.TryGetValue(name, out data)) + { + return data; + } + + return null; + } + + /// + /// 设置有限状态机数据。 + /// + /// 要设置的有限状态机数据的类型。 + /// 有限状态机数据名称。 + /// 要设置的有限状态机数据。 + public void SetData(string name, TData data) where TData : Variable + { + SetData(name, (Variable)data); + } + + /// + /// 设置有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 要设置的有限状态机数据。 + public void SetData(string name, Variable data) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Data name is invalid."); + } + + if (m_Datas == null) + { + m_Datas = new Dictionary(StringComparer.Ordinal); + } + + Variable oldData = GetData(name); + if (oldData != null) + { + ReferencePool.Release(oldData); + } + + m_Datas[name] = data; + } + + /// + /// 移除有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 是否移除有限状态机数据成功。 + public bool RemoveData(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Data name is invalid."); + } + + if (m_Datas == null) + { + return false; + } + + Variable oldData = GetData(name); + if (oldData != null) + { + ReferencePool.Release(oldData); + } + + return m_Datas.Remove(name); + } + + /// + /// 有限状态机轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_CurrentState == null) + { + return; + } + + m_CurrentStateTime += elapseSeconds; + m_CurrentState.OnUpdate(this, elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理有限状态机。 + /// + internal override void Shutdown() + { + ReferencePool.Release(this); + } + + /// + /// 切换当前有限状态机状态。 + /// + /// 要切换到的有限状态机状态类型。 + internal void ChangeState() where TState : FsmState + { + ChangeState(typeof(TState)); + } + + /// + /// 切换当前有限状态机状态。 + /// + /// 要切换到的有限状态机状态类型。 + internal void ChangeState(Type stateType) + { + if (m_CurrentState == null) + { + throw new GameFrameworkException("Current state is invalid."); + } + + FsmState state = GetState(stateType); + if (state == null) + { + throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not change state to '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), stateType.FullName)); + } + + m_CurrentState.OnLeave(this, false); + m_CurrentStateTime = 0f; + m_CurrentState = state; + m_CurrentState.OnEnter(this); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/Fsm.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/Fsm.cs.meta new file mode 100644 index 0000000..b54c354 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/Fsm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c571690223c4464b9850060eea6c82b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmBase.cs new file mode 100644 index 0000000..9c74ab4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmBase.cs @@ -0,0 +1,113 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.Fsm +{ + /// + /// 有限状态机基类。 + /// + public abstract class FsmBase + { + private string m_Name; + + /// + /// 初始化有限状态机基类的新实例。 + /// + public FsmBase() + { + m_Name = string.Empty; + } + + /// + /// 获取有限状态机名称。 + /// + public string Name + { + get + { + return m_Name; + } + protected set + { + m_Name = value ?? string.Empty; + } + } + + /// + /// 获取有限状态机完整名称。 + /// + public string FullName + { + get + { + return new TypeNamePair(OwnerType, m_Name).ToString(); + } + } + + /// + /// 获取有限状态机持有者类型。 + /// + public abstract Type OwnerType + { + get; + } + + /// + /// 获取有限状态机中状态的数量。 + /// + public abstract int FsmStateCount + { + get; + } + + /// + /// 获取有限状态机是否正在运行。 + /// + public abstract bool IsRunning + { + get; + } + + /// + /// 获取有限状态机是否被销毁。 + /// + public abstract bool IsDestroyed + { + get; + } + + /// + /// 获取当前有限状态机状态名称。 + /// + public abstract string CurrentStateName + { + get; + } + + /// + /// 获取当前有限状态机状态持续时间。 + /// + public abstract float CurrentStateTime + { + get; + } + + /// + /// 有限状态机轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 当前已流逝时间,以秒为单位。 + internal abstract void Update(float elapseSeconds, float realElapseSeconds); + + /// + /// 关闭并清理有限状态机。 + /// + internal abstract void Shutdown(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmBase.cs.meta new file mode 100644 index 0000000..f9b5e91 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41eea376bfd1a4f4d84cfb270e451fab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmManager.cs new file mode 100644 index 0000000..1e916d6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmManager.cs @@ -0,0 +1,411 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Fsm +{ + /// + /// 有限状态机管理器。 + /// + internal sealed class FsmManager : GameFrameworkModule, IFsmManager + { + private readonly Dictionary m_Fsms; + private readonly List m_TempFsms; + + /// + /// 初始化有限状态机管理器的新实例。 + /// + public FsmManager() + { + m_Fsms = new Dictionary(); + m_TempFsms = new List(); + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return 1; + } + } + + /// + /// 获取有限状态机数量。 + /// + public int Count + { + get + { + return m_Fsms.Count; + } + } + + /// + /// 有限状态机管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + m_TempFsms.Clear(); + if (m_Fsms.Count <= 0) + { + return; + } + + foreach (KeyValuePair fsm in m_Fsms) + { + m_TempFsms.Add(fsm.Value); + } + + foreach (FsmBase fsm in m_TempFsms) + { + if (fsm.IsDestroyed) + { + continue; + } + + fsm.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理有限状态机管理器。 + /// + internal override void Shutdown() + { + foreach (KeyValuePair fsm in m_Fsms) + { + fsm.Value.Shutdown(); + } + + m_Fsms.Clear(); + m_TempFsms.Clear(); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + public bool HasFsm() where T : class + { + return InternalHasFsm(new TypeNamePair(typeof(T))); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + public bool HasFsm(Type ownerType) + { + if (ownerType == null) + { + throw new GameFrameworkException("Owner type is invalid."); + } + + return InternalHasFsm(new TypeNamePair(ownerType)); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + public bool HasFsm(string name) where T : class + { + return InternalHasFsm(new TypeNamePair(typeof(T), name)); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + public bool HasFsm(Type ownerType, string name) + { + if (ownerType == null) + { + throw new GameFrameworkException("Owner type is invalid."); + } + + return InternalHasFsm(new TypeNamePair(ownerType, name)); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + public IFsm GetFsm() where T : class + { + return (IFsm)InternalGetFsm(new TypeNamePair(typeof(T))); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + public FsmBase GetFsm(Type ownerType) + { + if (ownerType == null) + { + throw new GameFrameworkException("Owner type is invalid."); + } + + return InternalGetFsm(new TypeNamePair(ownerType)); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + public IFsm GetFsm(string name) where T : class + { + return (IFsm)InternalGetFsm(new TypeNamePair(typeof(T), name)); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + public FsmBase GetFsm(Type ownerType, string name) + { + if (ownerType == null) + { + throw new GameFrameworkException("Owner type is invalid."); + } + + return InternalGetFsm(new TypeNamePair(ownerType, name)); + } + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + public FsmBase[] GetAllFsms() + { + int index = 0; + FsmBase[] results = new FsmBase[m_Fsms.Count]; + foreach (KeyValuePair fsm in m_Fsms) + { + results[index++] = fsm.Value; + } + + return results; + } + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + public void GetAllFsms(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair fsm in m_Fsms) + { + results.Add(fsm.Value); + } + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(T owner, params FsmState[] states) where T : class + { + return CreateFsm(string.Empty, owner, states); + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(string name, T owner, params FsmState[] states) where T : class + { + TypeNamePair typeNamePair = new TypeNamePair(typeof(T), name); + if (HasFsm(name)) + { + throw new GameFrameworkException(Utility.Text.Format("Already exist FSM '{0}'.", typeNamePair)); + } + + Fsm fsm = Fsm.Create(name, owner, states); + m_Fsms.Add(typeNamePair, fsm); + return fsm; + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(T owner, List> states) where T : class + { + return CreateFsm(string.Empty, owner, states); + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(string name, T owner, List> states) where T : class + { + TypeNamePair typeNamePair = new TypeNamePair(typeof(T), name); + if (HasFsm(name)) + { + throw new GameFrameworkException(Utility.Text.Format("Already exist FSM '{0}'.", typeNamePair)); + } + + Fsm fsm = Fsm.Create(name, owner, states); + m_Fsms.Add(typeNamePair, fsm); + return fsm; + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm() where T : class + { + return InternalDestroyFsm(new TypeNamePair(typeof(T))); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(Type ownerType) + { + if (ownerType == null) + { + throw new GameFrameworkException("Owner type is invalid."); + } + + return InternalDestroyFsm(new TypeNamePair(ownerType)); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(string name) where T : class + { + return InternalDestroyFsm(new TypeNamePair(typeof(T), name)); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(Type ownerType, string name) + { + if (ownerType == null) + { + throw new GameFrameworkException("Owner type is invalid."); + } + + return InternalDestroyFsm(new TypeNamePair(ownerType, name)); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(IFsm fsm) where T : class + { + if (fsm == null) + { + throw new GameFrameworkException("FSM is invalid."); + } + + return InternalDestroyFsm(new TypeNamePair(typeof(T), fsm.Name)); + } + + /// + /// 销毁有限状态机。 + /// + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(FsmBase fsm) + { + if (fsm == null) + { + throw new GameFrameworkException("FSM is invalid."); + } + + return InternalDestroyFsm(new TypeNamePair(fsm.OwnerType, fsm.Name)); + } + + private bool InternalHasFsm(TypeNamePair typeNamePair) + { + return m_Fsms.ContainsKey(typeNamePair); + } + + private FsmBase InternalGetFsm(TypeNamePair typeNamePair) + { + FsmBase fsm = null; + if (m_Fsms.TryGetValue(typeNamePair, out fsm)) + { + return fsm; + } + + return null; + } + + private bool InternalDestroyFsm(TypeNamePair typeNamePair) + { + FsmBase fsm = null; + if (m_Fsms.TryGetValue(typeNamePair, out fsm)) + { + fsm.Shutdown(); + return m_Fsms.Remove(typeNamePair); + } + + return false; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmManager.cs.meta new file mode 100644 index 0000000..6586071 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d195a2b83a404c409bb0bc49af63d88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmState.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmState.cs new file mode 100644 index 0000000..212b003 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmState.cs @@ -0,0 +1,110 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.Fsm +{ + /// + /// 有限状态机状态基类。 + /// + /// 有限状态机持有者类型。 + public abstract class FsmState where T : class + { + /// + /// 初始化有限状态机状态基类的新实例。 + /// + public FsmState() + { + } + + /// + /// 有限状态机状态初始化时调用。 + /// + /// 有限状态机引用。 + protected internal virtual void OnInit(IFsm fsm) + { + } + + /// + /// 有限状态机状态进入时调用。 + /// + /// 有限状态机引用。 + protected internal virtual void OnEnter(IFsm fsm) + { + } + + /// + /// 有限状态机状态轮询时调用。 + /// + /// 有限状态机引用。 + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + protected internal virtual void OnUpdate(IFsm fsm, float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 有限状态机状态离开时调用。 + /// + /// 有限状态机引用。 + /// 是否是关闭有限状态机时触发。 + protected internal virtual void OnLeave(IFsm fsm, bool isShutdown) + { + } + + /// + /// 有限状态机状态销毁时调用。 + /// + /// 有限状态机引用。 + protected internal virtual void OnDestroy(IFsm fsm) + { + } + + /// + /// 切换当前有限状态机状态。 + /// + /// 要切换到的有限状态机状态类型。 + /// 有限状态机引用。 + protected void ChangeState(IFsm fsm) where TState : FsmState + { + Fsm fsmImplement = (Fsm)fsm; + if (fsmImplement == null) + { + throw new GameFrameworkException("FSM is invalid."); + } + + fsmImplement.ChangeState(); + } + + /// + /// 切换当前有限状态机状态。 + /// + /// 有限状态机引用。 + /// 要切换到的有限状态机状态类型。 + protected void ChangeState(IFsm fsm, Type stateType) + { + Fsm fsmImplement = (Fsm)fsm; + if (fsmImplement == null) + { + throw new GameFrameworkException("FSM is invalid."); + } + + if (stateType == null) + { + throw new GameFrameworkException("State type is invalid."); + } + + if (!typeof(FsmState).IsAssignableFrom(stateType)) + { + throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName)); + } + + fsmImplement.ChangeState(stateType); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmState.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmState.cs.meta new file mode 100644 index 0000000..c38b534 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/FsmState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f1d5955fd4cda84f8c06a860817387a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsm.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsm.cs new file mode 100644 index 0000000..f97563b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsm.cs @@ -0,0 +1,179 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Fsm +{ + /// + /// 有限状态机接口。 + /// + /// 有限状态机持有者类型。 + public interface IFsm where T : class + { + /// + /// 获取有限状态机名称。 + /// + string Name + { + get; + } + + /// + /// 获取有限状态机完整名称。 + /// + string FullName + { + get; + } + + /// + /// 获取有限状态机持有者。 + /// + T Owner + { + get; + } + + /// + /// 获取有限状态机中状态的数量。 + /// + int FsmStateCount + { + get; + } + + /// + /// 获取有限状态机是否正在运行。 + /// + bool IsRunning + { + get; + } + + /// + /// 获取有限状态机是否被销毁。 + /// + bool IsDestroyed + { + get; + } + + /// + /// 获取当前有限状态机状态。 + /// + FsmState CurrentState + { + get; + } + + /// + /// 获取当前有限状态机状态持续时间。 + /// + float CurrentStateTime + { + get; + } + + /// + /// 开始有限状态机。 + /// + /// 要开始的有限状态机状态类型。 + void Start() where TState : FsmState; + + /// + /// 开始有限状态机。 + /// + /// 要开始的有限状态机状态类型。 + void Start(Type stateType); + + /// + /// 是否存在有限状态机状态。 + /// + /// 要检查的有限状态机状态类型。 + /// 是否存在有限状态机状态。 + bool HasState() where TState : FsmState; + + /// + /// 是否存在有限状态机状态。 + /// + /// 要检查的有限状态机状态类型。 + /// 是否存在有限状态机状态。 + bool HasState(Type stateType); + + /// + /// 获取有限状态机状态。 + /// + /// 要获取的有限状态机状态类型。 + /// 要获取的有限状态机状态。 + TState GetState() where TState : FsmState; + + /// + /// 获取有限状态机状态。 + /// + /// 要获取的有限状态机状态类型。 + /// 要获取的有限状态机状态。 + FsmState GetState(Type stateType); + + /// + /// 获取有限状态机的所有状态。 + /// + /// 有限状态机的所有状态。 + FsmState[] GetAllStates(); + + /// + /// 获取有限状态机的所有状态。 + /// + /// 有限状态机的所有状态。 + void GetAllStates(List> results); + + /// + /// 是否存在有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 有限状态机数据是否存在。 + bool HasData(string name); + + /// + /// 获取有限状态机数据。 + /// + /// 要获取的有限状态机数据的类型。 + /// 有限状态机数据名称。 + /// 要获取的有限状态机数据。 + TData GetData(string name) where TData : Variable; + + /// + /// 获取有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 要获取的有限状态机数据。 + Variable GetData(string name); + + /// + /// 设置有限状态机数据。 + /// + /// 要设置的有限状态机数据的类型。 + /// 有限状态机数据名称。 + /// 要设置的有限状态机数据。 + void SetData(string name, TData data) where TData : Variable; + + /// + /// 设置有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 要设置的有限状态机数据。 + void SetData(string name, Variable data); + + /// + /// 移除有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 是否移除有限状态机数据成功。 + bool RemoveData(string name); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsm.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsm.cs.meta new file mode 100644 index 0000000..f0e7571 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68a04ab91d4f6a04288a73e004c86b6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsmManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsmManager.cs new file mode 100644 index 0000000..0f0854b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsmManager.cs @@ -0,0 +1,181 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Fsm +{ + /// + /// 有限状态机管理器。 + /// + public interface IFsmManager + { + /// + /// 获取有限状态机数量。 + /// + int Count + { + get; + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + bool HasFsm() where T : class; + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + bool HasFsm(Type ownerType); + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + bool HasFsm(string name) where T : class; + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + bool HasFsm(Type ownerType, string name); + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + IFsm GetFsm() where T : class; + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + FsmBase GetFsm(Type ownerType); + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + IFsm GetFsm(string name) where T : class; + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + FsmBase GetFsm(Type ownerType, string name); + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + FsmBase[] GetAllFsms(); + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + void GetAllFsms(List results); + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + IFsm CreateFsm(T owner, params FsmState[] states) where T : class; + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + IFsm CreateFsm(string name, T owner, params FsmState[] states) where T : class; + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + IFsm CreateFsm(T owner, List> states) where T : class; + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + IFsm CreateFsm(string name, T owner, List> states) where T : class; + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm() where T : class; + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(Type ownerType); + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(string name) where T : class; + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(Type ownerType, string name); + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(IFsm fsm) where T : class; + + /// + /// 销毁有限状态机。 + /// + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(FsmBase fsm); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsmManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsmManager.cs.meta new file mode 100644 index 0000000..8cee9ae --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Fsm/IFsmManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17fa8008d81863a4b935d453a45ddc43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/GameFramework.asmdef b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/GameFramework.asmdef new file mode 100644 index 0000000..dbe8ffa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/GameFramework.asmdef @@ -0,0 +1,14 @@ +{ + "name": "GameFramework", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/GameFramework.asmdef.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/GameFramework.asmdef.meta new file mode 100644 index 0000000..2408661 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/GameFramework.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bc1756600545274478db6a24483faf43 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries.meta new file mode 100644 index 0000000..ac0c9e5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1a46d69a0c58378428a0f12b118e5571 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/ICSharpCode.SharpZipLib.dll b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/ICSharpCode.SharpZipLib.dll new file mode 100644 index 0000000000000000000000000000000000000000..fe643ebc638dfc94f1149528d0e9a91ce52dc353 GIT binary patch literal 200704 zcmeFa34ByV);8X`xBK>%gj_ngoe)SjV4&&F)*V6iMcly+w**uI;z9&k6Ia?s)Dd?i z5|=^1ZFJnl9rxXFV?;znSwzQW6n7ohQU1?!>h_X=&b;qC-}n1}-)DZgT~((}ojP^u z)OMR)=FHT>g!f-{1b3kLcpigT;<}ysP@IESR{e?}5k6Y!4sT zmOQ#`+U)QV)8@=co)DgXWVr3bIpLXe!n^EyKzMd?#*uYJMZO(u();b|a7--F9hD=0 znvltDvqS6aFYq`Vn>B|cte}T)&G^afSOqUpd=rEG%imbU1OCMt9pxH(wgeE)x#Cl} zgo3WhSa+<;63Ip*AKg)y7yP%qVTS`H$o_c{-Xj}wIO`&L;CBi9E`i@A@c)nm#&TVaKdwzRhs*KOq5{V*a|#?@f#!bp3p*V1 zbHQKrc^^Bd@}Jk=GU1?0CQW&2#A|y_dTQ>x8~hLb>9jkG9vNSJ-s%sZxG?!b!3k@2 zTz~KEDTnUzr_aqijxZ0>^Sk*-FDr7=dG{2bNsO%efRO>C!ccTUUT-JpC!L_lR6`?U0j4rf06-_s9DRW=uJ7?J?1xURbqh%A3|_2Q8{w+q1Gk zckBu73LFkotI_pZe;d5VwfA&5d~>z-B8S898O~%6xP~6)D*2)Wup@5)u*qlC7)BEK zz73mv&Kg5c2I!BHUT?~$+|euH@Uifk!*tY+R(|HWm%z4@r|xPWW@kDQu4eqJOtoyL zD$fc>uf|-Sbz_vjN{f_&x9G8`zSVe6NB-}C^XstW2Rn{hJRboz1aaTNeG}oe@UMdZ zS>R1YcnjS30s9KDdl7ye?nZ>Cz`rlzo`!!mp3!(H(}i%~!n2O~;JF8nh35-AMWY ze=__x!+js_#lR_rI~{R@0J{$EbcC0{e?8)Eg#REs%;PA8|Au(h;d;Oxgx?L9a;U&_ zJ09k{8SvKt-vzFQG%W9<@Sh0S06aqwj^Oz#V6+$B0e>Z)`G`9m&ni5fc)kU#-2p!t z&x`Pn2W~4|^7|6}mjON#j~5SR(SYZE_^(FX&hW3nvoHKR0M-Kck4X1CV7DTCA>13_ zzJTX3z(?bmhKIU)HR6r~z6t-?@Ke|O<2fAh7XW@39?IwlxH|%VA)aZ#bHZH$SWm?5 zf-uX*{M+C^3C{<3F2d6b@jt?)K2q2B2hLSUOT03;X@su?ju+vZ5w3xMFx-6rKLq|e z;LgYMBOdChfw-6O1Q7Qj+|!YcdP4jbxbxsP1O70cqY!4BCx52_{tjH~-XnOZf6MT& z>2Y$8@wvRIqehAMM@V^H4Jh;arj(NQZyfobR5WW-sUE!y$7Q(+A{x1MO z3J?1i;&|JeGvZ?!a=xoh`SRm=?+31`>I3m3>uVOC5%A9f>}0rW z5oSMi7W@r>?TLr_GmUV#p9B6S+~IiM0PU0DvTa_C=R)AHeX@UJ8($09X3~bc31Oy> zPAHee`z`jNJc*L`4ui#)lRfNm&Jb`Bv!YhDN0skN1z6F8To;}cV2q<)%mAGF^(f%i!~Z?tSHQml{wMHI z2iTsyfWL@v0?$&wSpUpt6XKZu8H9fU&XIW7?k53084v5~M!55UGbil8??q@b1=Xu- zbcZuyVOlWXkKQagK+~O(a?TPkTd1JhPtzm4=#i+(tj~o`h)4!qBDv`iBy3_BQS?oi zRIpz}wx-sOp2tXoqEiby0K8}zvQL9>CX5mlqeuzcKtmbSY*;(MgWcgq9izKoVv4WdkU%FY2?hVUWp1 zf|@T{*9M^;*WMTYxsw!$8ox~n;vmAzEJ9t|oq2w}Ad|4JZSSmK>a78K>x;#z}yjfMx&#_Te^d zEfql~HCkCzOR)xgT8cH`cL$qyg)%w9_5)>=2`s}s@jz)DF=$>LGKyJRq@HfE76H#j z3_^~>&FJ4gz}2aLRvN17R253CGZxjJ@q(QTw zL`v%@E^&CErv(Az!LfsRP%l9qqGB37@uebZ2b)8osYe8L{7w%xPxaZ9^=6^WPPIy; z{)+Uolz)_cE6S^MTgCc}s_8aj%dh*vXQ06?>oc@5vo|L?l|IWKGYz-u<3_TNa|fIJ z?%s(lp%Uq+3$3D<>G9@jf2lXvROAhnBtEtR&RDa@bfP_30aq-frP#cnO(l~}S5saJ z(-mwAxS(JqiS@C*R)B3c57%h2mYQf~0mC$a@}B90U+5&R(IV&v?S@(26mV-5B9DMa z3-wSwuNCmc23i4s%rN~(=+9(a_l1_?C}H|c|C*(y4{<*Dy@^+Q%a9T%v;sx3VzbaJ zGK+vv1O)g@PvR3RP#oLYPF>s)=mDG_9f6WqPkQ(Sn>&{B7g0T|hL6lb%Pc`J!a>R` zhSw|xv0`|=iIrBsj7`ug6}LUDKp+;kS*-P#J%QH~oc9E+o>|V{HcWGg88Cakvdjzs zBLKfUvDq}?H}U65++hVuW9^}Epv($bRv;J~U|NP*y2K1FW=6h%WtL^a=p%fAGBb$8 zK{E(KYt_gGbTy!f2dSL!NTM>+GTo7#MDj=txLLN`ECqp5cs+@8M3-D*C-6X*q<0jd z`odQ)C~#=0GNhVZsA-|{2pX7?hWP134O8tus9GsBYr5%gp>o-B^(-;H zoeftqjF#^-CERQ!tZoo#b%}g7w3Ji>5_C=5>34e@3!?5Cw>vm?JcgpOKw&UYu_AY{5rJ~EXflFO=IK!8|Bh^S`ClN4TYsZm!*<%bb*no#q5+Osh*~IAgR^0E zbOefR%_zPY9dkkT@%%Llo6evc>yLV%3SgY3qoptt!Y}=1@lw!gh9C;9hII<&8ME@2 zty?2lzZyethp&5Trt>6Rf?!}Kf_ATRSNxy{$YUa?c*xH)i?$Sr(OHxjCjX_Yz;B?$ zEU_B47?#;%>Hi58GxYqQdBh82hRg99Trb;s0aQ<>!al>YmMigCMo`*68@ey(kM%a( zd4i%OJC(3xWD(T(2CFcJNf;~4(@~_Q!tfa0PS0|~o0rxWvM1P7h=$DiiN9Ft!0tU|FDufR3<8OBm6|fdG%5sCKRO~z8;qzH!7PN+MF;0BpTgyz zmJ%A0-KggY&{8Co#v~K7AX~|pYlq4r!wx|(R7Fz!b!A$4X00X_ZdYV=iXq5C zfD-66<{B2LYkgrvV-<$!r2ZGxm*kOOUu&kVNej?QW4i0qdZ`k~;w73Xk17c3;;?MF z1v|y0^);EgkP7Zzv*^i)i}KUS((GCpb`wz^9Nump#+oxfVTuGC-eZ=?&$2$lDOWoU{z$Yrx1$H{`_x zVO4g5faL_CdTl{era1a!pJpi21bZ>~(OwJEVfeA`{+j8qcJj@wYnz~DCK+{Ym~-0` zj=HwjvVQ4fX=U({A78Q49}A&_?CJ6>b~k#Q2D(KU6{H(1HWD96KU(ZUCt4Kq=w55N znvn++Uvowt(p{!=ajB_@GDBD$MXY9emTb!Z!wfxChD46&h zGqYl6z!TfSbn7Nq>%?zoGiT_g2Q#(i<@lM7=^CN}9@7JMUoYmo-W#jXP0q!TSFkBK z9f3|D%k<0i0_~k>R6~74U?q~inJNm=&?ez1!UL%~PQ^pJ)~*1qE`+@ile`1l9gd%y z3mo4UIUOGjDs()Y-a-2H)xhPS7Am$4U)b$ZhOhKk)?6?>j*c=@?MbhUQOZoUS1!!e zQF>yx@ZJ&@GnK^e(=EKOgtHc;^uY|5r4OYeh9;PapoxYSN~8|~kZOmgL~{n~^jAmeJsh#1`QZ4u$`BecbKPAd5g%2);{i{q%iFyk}rUW8ARs6)e z$`u1yYh-vo!keApJWy|1m=UUS_tas13cE zgERpC%cB1O2S;&D;Yaq*_76&BX=~mMg+fKLzi2`=@(-O3`wJ~K9dWhw=mP0c3Sh<2 z!$8-vZNMfviJ)XZB-<3!VdagC0D$&p=`jL;Z-~+krh)$0v5p|~fni%>nJW4%X1L@9 z&J;SKog?TC(eq8V-D7OGK})gEYf?cgJrx1fzQ=(k+qY6=Wp*qRb%c6j86i!|QbuXj zO15aWL4p(~hf15%EkX@+&?l`VllW6=Y}FS;F`r=@Nz!6DJAF93fRKUUbmfY1k^t1d zI4L4c6DGAtixens7i666Hrwt1+dZHwToV!zbpL4eyMkIxxfTpY4q~`EMOmTE(TTx! zY$wO56p3k!HPR)6XTqzdrzL51iiE0~6}@UvN0di2L87dN``FKL zoq5WCns!zFeKtGJP*{`fnswT7rnlsCr#A_AG`H#^Uob@dpuX`BU=&lCfR+3KDCq{M z>K4vJ2Vrcku|lcGE=PYi+9UM%U)f+S8nD>!!}JL|XK^fS1$xAK7-sPjvqz}MGMFHn zXo7^9aZASJ*gLUaOCc+#)!>TEpbkkW{2ao z2*wK12)B3%sRTstP3vd?wmL=xOsjC{l^_XgWXY5O&6=KIGfc&ti<;O2;zY;WsZ5tW z>)l>X_!94WJ@El%iCI(^hGC?x64us|=JLaWjb<)Mb07fJBHA|xnx&qEX_k5$3dNAJ z#4NRz#rzpR1(2~x!m3MCOP~b#7lNliGYq9A)~Lf^RZ_cxVkwQ4nXqlVgC88_MN~w-s@b@x%0TnZ74`${TjTn^O$Oj8>)F_l_LNUDxl(1bXcyDA^ZuYj8 znY}@yx7nN7nMJ+FUITes)q#H1fxgv&aCIP59jFTQ@dWzEuycZ0q|@wwNni)Fk6|q_ zcUXK((=mZQW|a}l1ggxCQJx8e%&<|B353nQ28y84^fmh#m6?7*6QQ= zYnTIl4Kum~iSYwVa^y%fGcyX*s2K$-?`BNZy~aESBU)*o ztTYfT4Zt>A1^Xh~r0EGe=A&hK;o;&TuE4!7;vymtvjX+ln24G6WSE<)9C&fFE>LTO=$N(3%o?+<@m(`!nRS?4azSD?m~qf; z0Dc4fp2Tf-6G>QsMl_Lx*_hu%8iChnHlm4GfgNK>Y&!U`-C_j>$Lb7o$0g?A#il>* zwY>o}PX+VUXJI~bFlY=m2cu=YWcp!yx5eNK*4w@WQb|he*1%AI6os@S676X2h=N~W z??wfNSb?2lJDNkxovfu+U}&t58uZPbxal;sX;F>AxZqNADAEo!hhjfzBf?FAorscn z)(Q-Zg@7__QH?J%$mWJsa~Lp(nZvkIWd(-E#sPEqqM9A8z=+r&JE!5yX#{fGUiuM8 zKf)Y=^sku1;U8`SJ@J5s9z%^Ap&q73d{$s&tj-FI!uGX2)|;b{V3aw^uA`BQ6Ypn+ zdvheBMw%m0RWDhA(XknZIeLk;I50-5G{@NF#$v~+yj%k27@&_a#}LaLyEyS7GAXaf zL^bC{HGG)OVl2{(HOHcco;63qKiV7(!Cz)!n=I3D)gSe%y_P31F1C|~u|`z0aB-$l zjk{#AiCN$_&`!n8IAk==9OsQcE&aBb|6?84)9_$BmklL42U|#5YCNI*m^3r~7frKtgWY@iccXcYB)sZr}%-tY5*eUQSCi>-HASX@quLj2u;~($ z4G2GjK3f6*vxFOx|9Prf3L?fb0K#>S{*YTFDNHk+!#2PhRnjw^*2u>ggzTM;;V2yE z^9kc0f4wWVhbnw3TAPswv9`s9?hC|8o#Kc{6TTExd8`V;3UCc6@ z?oQL&6m06~0`zPT2`oJ+H^h5Gcgh)#yHR#`2C%#$NxMOKGnBn%5$uo6 z*nVvG3*`iNeEcy|wsit*VIMD#Eq5ld+bouL!W2V;n5ua_^`o*iVY<6kyXom#@0@Gq zS3Rw4tTn^aoN(bM=41%l!KNFhTbfN*1a=?{z20W88yNVBVMgF>4&aTB@K-u|d z8fLtKG`l1-kd}rAilkskV?<}~1re`l7@39tR+K#cxuT3kZI-n#%IJu1vDxYfxPj7W z7Z0W4T8rqWyJ|XG<8~&4o`5^AjPa*~zSsbj#>m6AAz53xBvE;&FiU%+ZPkJ0{pv zHNCS71mR{IfP*@@SRW%AZeco~(htSY#h^O&H1rsjPZnv+ztHjz?L^&ss;0Y}&|R_2 z-cCq9?3gOQbth(lTerTwbt-#HLBjS$SRiQfJOWf0uhV$2qC5iI8b$zu&p5OP! z5u%FLz-*-G)n!sf4ORHgzwCKQ=j|kuq*{Lg`H$ zv|>f4IUJ3e zRmjoIZra#}OQ6@OKAykspxVI4hVU5-Zx2TqjWY4fIg8Z+t)cl}2`4@u9X#h?H-cX$ z_{EHr8%Qd4vUHf}LRE*E-jy*y)uBdUumq9Z943wly67Q`Ng9kDVU03$K}v~d0~ewFbpsq zg>Fp#-JV~xXl}yze;Fc&FNo-0lu9*Ky%Sv-8?m!9;Pjf#Is-rd72*7!Ne1f&N-5sM z_B59i=vXxr*a{x+VSAdnRf->@S2It~QmZl1qGMPiuf$5ll6ImyPDVS?IS*0?6n6mz zxA22an5(FLe3_;g404u~rpz>ievw*YOencACYa#EhU|e=~um|gi9cWw3445b(K+Krsho9#1DL9+30L9HD1?R_fNe#fZ>1~-%X-0p6dS^lAcP$7`X#Vdn zNTw8~yK5n~H?-lDMVc03Y`1^J9dGOr7;{kup4(o7D(FewVPz{*wL9ztQ29N1emN4| z8%r8YrF7HRiFcFni=$&z)0bz?K|2#~J8}5ibmJVK>EVyp3jMMi)4bS3OnCfdqI{+s z)3@broTGG`g;)dP1T;K+uvlHrUqpG#qE7rMU?=QtL@8RX7UZVi8NUOJg6T2m;YS96 zp{K(KBWWi{;XpFhgB&x1fnscLAa!vkW;n$-K7y?ccf)A>)c2AMu-(zAvg*;0kE3)J{cp>S1EA@J!N6-^^|IW=zXxkfPiJcw7w2uA zGZn2b>u;JFWRx2E8KHa)kZi^ugB>7)(bR&vGP3n!pn6zf3Qej<0#ZH2sGed7&K3`X zovM0pL>&?zH5bjq5WTTYCFo{?IITVy1~hD;xMD@n1Q+aK_Q@dztokh)&Y?G(PFRqg zuDBk=(%3$i?uy0OvW-BaG##(k`1BHo zfziSl_vk)nNr8b=GHN_wqZ)N4!fK_*h4VMZLTh~>i=fgrFJXV4`b59s@yHA+y~E_ z2|;Q4G?jYurCQaDX%u~{h#q^Pv(xkfWGN5#S}`EY9|mzomQ9l=P0>y;45YY9>4L}8FPP_{_`i#A9?=1hZdB+ImwmoQ-odl3xNGOvpMPlm z*dHFg^>4G*B~Co_?Ok6kdVNFls8?>ewc*VH!yTLUpTGYb&soz}KX&go_w?=m^xX&l z@zMuh?s5GiE0?d-BA#iUApC%*BVdC1c}{_*Ua zD~{anqx*Y)yzc{n z{jONO;+`Ad_)Boq-OXnd-BUN>&`0jSZPtU2htFF1>3w%Uwxsag`}8Gi?mS`G?yr4( z$H{A!l?_<$Jj>e9-qU}?-~KRSM(60(*+n-_Zk_9Yx%j@0yZ9F>p z_5(ls@cE+)$3J?1@U?|2TK<0B>#xsS{K_>?Ke=w`q_5uI_sgRndgbUt9=>6taqpN3 zL+;w+tys~ziIu)PzTHb7(lXaM?y1jP-ahE!v*z2sL9=>`_ zvUAjH=c~Yy!ze? zmcLok=k`rgRy;Z5$^l;;@yXKbT2J&Xo~_+vc$bbDQoQBtqup(RLmaL%_j>Ho(zz?& zy*+kkYG~zsg;y?Ib4k&ouf2c&=NnGz`}TVO+BL5(*!kVHUw(i0#$)E3^;T$=_2?N> z20ZZXJ14J5p1k}0|ZzcsJmD0HSKAw@|eRqW69`FkNWSqW?|t|m2bNyU-Y?FJ4Y=Huv*9a*|;>p zem|StDPOq8kmSpaTxm6Om8EAfdVrRqdsHhs650h4aJk-5a2#LJr{SfIdYCCN_cE~f zR1sCvTjw2%gvOc6kvDE(AuqJM_Mf?N>-}v1nd?(?uxx*tJLm~JLQfo# zQG-t8bYvwa1XtqYY`=JapC_DiMx5z=bHMnb4JSDR#~%Ak@UFcV^m6UDd)3NMJp+1t z@qEA6Uq8Qo+KUrnGp;Ng{OW>Lao^PoM?Uh%zC({&Z%+Knv#a;0+Prwzn|_`&?$+DN zrdF<4JLSpCEnaa(_`!A+)#Ao5oXEcqf5v3IrX~3Hl*jKt~zejQHP(f z`M&;F9CFLMOBY^rO~j_UPxkef;2%mYeQB zBYn)>f2gg$t+C;=n?AN~`_p0mSywNbome~YxUX0La`1|cdrmn1&54ym{_>OY-BbO- z_x$zJQ766-nLqritCs!r?QRdP{OQXZPTl&=x1-+~zh&$DOIAJn_uAFzPfk8=!H$p5 z-o2q>f^*dE2R}3H7URr;y(`D}e`b`Ut}XmT^yOs>d!90XU+bD13M;LLR)qpv&M)}W zw-a3H)gI3atDY}(-*WjWEABh^w3&;_j^A|A+7s7rTzu@T$0sH4{lJ{A{j~b1$9B8w zaL<&(C%=;JbI4IG8xA<4;mW<&)=u8D$X~I`gVwsSmp^;`t>N`EZv5frf!FV|`GadF zthnZ}f8N&eQ1u1<@4Mu(ckil?-FE&JLuM@;S5kl0w?&_w^Yvjj{c)GE$1GcRRBTZ+ z^>OEieeT)3pX0>$&Koe~qtPS2`*g&yE55$)q~pIkXurgd@9zEeFH^sG_}RaIntn3= z;^>zbyuS6tvlgs;ZO1E5edW_fhHsdB^-t?Q+gv!a`R7%$=dWMbveUEs&PZJ5nS1sH z&(Aybw)5M!te9}}!9~t}-zj-!!q6cLcDp#X`_AX59EXlN>WQZJ#-4f50f&v>fBA?$ z)q@6X==+7^s+!&V93I(u?}{P+*l%5;=Aq>V>)zwj%Y9qFIJo%7 ztId+VA6Z@6dFA4Y{tG7cDL%OV%LgWW_K%j?w|)P{akKupCLDYB$Wb4E@Nnf#Tl~f` zpWpY;z&8qR_~6xb^RM5OTsGsa)>ZwV-njbR$DQ9^v+C|GEzi%pX!Ik`FWUM*$$bys z^XFUAE3W-%`0ZsM{B-k6kFWf5YU8QbJ=-$m%Hz}DU3KG>doBs>cH(8dti-vu`M1Y3fWA?IkpS8HbIc+g+)0`?EqlXiR z)n!Zp2|+)&OArhQ5(>vPQ3G5Y>cw~hi-gl>l>Sm+{Zim}*Ywt%?Te6Qp`m$_H?Ulu zb0|QIBO`7hG+{+A7q*$|? zyJoz>bD!9z#6sM+q{v%iYTn4*S(I9BQ{PP{?ty?wIC2-MYQOZ_3rYS$5-!pq^mGC7{{*)mv9e~l~1cCUDGX0BYT)oq?|Shygm;D zAYQXI{mAPnelanyjUx-JT^ihvO%?6QZp60q|PMq40-djTQpIOkA)z zISgPNp3R}u{t61t38C^bEQ%$=4RI~bG7G-c9TFvux#uf>slT+Eg}`sP!6>GF$k3bkQ>MOsa9JNilZ%Zl2EgD)I(;?59`NZ^dAL?^Jx>`ab8Tyi9S1`Iuy zDZNrSqjC3q%#yZhNT)4H5sd=wT(^xE0Yfnh#}=JNatw)>&^@7`g0Y>tVkXMF=85A& z$+1X>L$h5I+B}Y#21v7@?C<$()JB9B80@k)grc>*5vu2F1Wa4!EG z^6pE$6%oL~raYpx=v{`QD{~m`CBx7=(Y3XK^^1_LzO~X{7v=!aX9R*7{G2}LP@vD- zMR5XJ^29 zdev)o&{Z)S+-+w-4`YTN*#p&sjY6WklTRWg2G`HDzM#mz)6;)IgfCfOju? z7tpImI4Ww+$cuDbkyUX1%V}R$X{9!f@u;p^NMW z+Oktp!~INaf$M3&y-}~z^NSNLEi0FE$W%ry%xN3B2nN_^WEPXaZR8>t3ES@bCK&{8 zY|ogus-{;5!Bu zGh;dr82kKIYoXOzRP2VHyNcaKn4~8$0r1rnYsnB?Eg8mdb5XJ3@wTH5aq7}ljO~u( za`^d<^vt{>a*|}l%WzV#wW$#MlPIlebStjp>gL;3c#WGcR{3fMfR18jySX5<^N<+? z)rpgwW!uHU;HQi~85cFe`N2DI2U31MZ5SFrb{>FEj_(A^wB^t`f5uzic%qsL1V`UQ zj9>->XV8_mek^A4j&gr_Va%yERHYMcsKVqrOU?GyH*Qp00u8U_q1O9=ivG*zi|rvD zw-0ZF2$5iXr%X1(8*9po6to;?smpV;ZEt;}R#Ak_>0~o0NxK1Gj#CcavFCY5@7jM6 zJbaI86!a%z>(7L2-D?YH)|Rv#M0FLQsB6VVyJDEHUd>sR+(S#u|mHO1yAp;*n6HoE|9jkd)f-ShLg< zM4)O$Hdu}zc8;>)3Wm#b;a(t~jjTiUlOkQbr6#33KT`Kd#G z0`jt^ZcT=iRo|q`9eaZ)(-hRwNzz-f`&EvM#f;#z$yGDf08xkRFJgt@kG)oVR`%$y zLWOl09|)NOvU4>h`8261nwDPC5h|aqmv>;ZtVIvvsA7w5b+jy3(LueBME6$Fl@i@6 z8;#2v{1PAXDTI($FsgvTGLW}c;S3rsWxzCrnOm3Ys_yJ;YzI3@Di*cgEhbz43Xb;> zlt^r}JaxeBhl&a>#UWBK<0-e6XIn3p+aEyBFslCz4w&WH_cHJbujx|vXR)g^tjI?| z7?2$=8h{f6j?)+0K{q=5>`Q4Ybs?Zd-UaS7+*;_4ya%5cPGMqAyzYwng1LWG^ZU%T zI}^Xo!Z$L%cv`l}U~o zaBXFMJIjZr=djZx#c@+}guz!W+l1ZNC91szba@<)c*$u9U|y?Bl$M;1VEc!ZcQ@GQ zgrP3bbsNziS=)T0g?1}6C>nhh(h2iOpE{LvF~gx==}X|cYW!_(4}^wAG=)ZaEJPoO zy1`m#=sb9}R0k8J(2qNL43Wv)%{X02Ityp2=w?s-1PjNEh=g}#Dpf2dfqa*dCb^!0w>Z;5tBspHIOL8w0t+B{C@~w4I(5 zLnXR1X%w&xgi4xx2xBq>Vk)jlavch09d5jwF%&;M#J>#{6Z_aU6}%eA<6%q>ucVKa zARQ*Xqp|{36p|j~i-TCW+$4f?6`l?y79}kl4DW#Ern6}>7o3EAi8V2|;Tn_Tp^9j) z_8F`qaL9QM?Lqa_9~s4Q4`N-|6$;l?w%zJ=9Ot?aMxuhYHSqF9LZ7N!)Rn7zO5Lbl zywVm&_OWtq`w=MDqG}K!Y2Yt!Yw!uMLXiQ8@6OpoV9>;pkgu@QQTp^p0zxI}C2)18 zyeQLtG*bB5kHN3sUC!6)xjU3gas^N!UIKV+gb$X!T%bsEd%Q`^XnpC+N!lnEob;6p zc-v<&Vk!N_&NOCK_8AMetZ5r4lN6z~aEXQXfI6FvL@?tF#YztfO-@54jr(B0mPv`0 zB17)HleNL7HPwZ3rq)xlQA-IQf`qPL1dw8>t>hfi#i0XIEOr{jI4WT{`Ff5BrCM^T z#yyaN;O#)CswWdPOovFyHG zQsU;cWKtLjrWvj1C65CL=f3tsb+#W5|6C9x?<6d)>dbLgm&FrPMRs73*UMdY&tlMp zS-AVP%$S9@<1%SOJ}D8gpyU_}paDFItAZFioeoUjCYJ~+ zvmu=S@VC9dU}oj`XQp$eucw1AT1-Nw=^GGWQAkq^>f%98lo!fNnVDFQf>v%@P)m`N znz7@>a|ZNavW>#iqhWqB)2AD)^}0UOr|x3%2MhJ0SZ^qEJyyed-P?@K)D#&jO-=`o(cQEZc}~8GK&=*}^@Z~ZEq69Wu#<-%-fGxErAeDf_92 z1O1tZy0*D_{xy02eua5BS^q*UbrZ^2+Y5C}kE#{kQpu<*1y>qPpETUiF!ZtD3;tSAH6yvb6z=c^C?v4&%VOI^^0L8#qf0g(&Zw%2 zGvp1A?49Jx8{Uk}rlMZwW)t%T+E`vvzGT=fvFVc3_Q^nJ@5E|vuc^b{ z0x8}X)+I6SZ0(*{i6nE`Yk6XIUS?JTb(fW9*OYk?d|fMx#rHL>gbQa_yB5(@Qot)b zid(#8V|sB_E3XUg!XqyV?UuAqC6POYu_@w9yzH%-TGJTALCzwH%FDkxP-HcHXcl#+ zp%8IfvYoJa+l0kTSlm6KLiCnTt-;j}xnlAT(JpM}NAfP>E|F#lirb@wH;)?06HwPP z)nX2c@?5sA(Fd?01=-iJFXp!+Fd;FkGGmss;`LDMvN==HMUa_l=>qLGwGmNGNn9q9 zX=E?LTU8jd`$wb7)9gte1{f3&z573zvos96dI=?NScjWl)%w*4+8!(jjdI)1HKHL4 z#um4XVrHS zmYffEV|!>R2DB8hF<+tso8EbdV?T2^S1Ftag?2wtE^RZB)HkuriQI>|GTu;!M$ z0GN)FX&Et8I5o$e1DKIRx#NA6}rCToDo*ByA4MQ!zabvdQu3N*WN1_;;BAd~8 z{216u)kIe~03O$0huAW8Vd)4|X*K)LyBE3F`r1!Gwauqr0IvO#Cjy`+4+Ub?6rbjF z?Pmnru{toMP{pVPl2)b1hggjLRlOZ&=kXt}EWEOwt1JdkS%+pT%buQOBpUs?@c8pXcAh%)zhC^Z%IV->YX1XJyuZlC4Mh$Pq^Eky*tP1&Yd@ zW)mSB{%NVZDf97YSM+GfM!}{$ai3OXLN=7IMw_r%MeX6-M~cO{Pv#!89u8cAUP{`R z{2Mx&=|3~}oS^DI4NG6D8CFp2#5k-XjSZ`uB)%JC7b!RE*%wUW#tStIxsRpL%YyB5 zf$3B|N}C=;ga3l^QIl;&E{PAp$jnlj^#TSy)>8L_08Akfe9;T-m7ySdu75JIvdpEJ z1$mJf5={~K76^?_yeqDj1;?Kf~aWI9jrahJiz1)FRTieK1Mi=2dH;k(eG1%vG;!(Y@>7g%$6{$*D>RsxZE@|dtlcLw=eX-7b9G?g_`M0leiNL6fLz8zR=iulw+EdV-vzw1Io^b zis_gTH#f(6s-XHcorg77Ob?U{eGXFrSM5a2bf#H2&2*(%IKK78!r^R9nuWs+x@i^; zm*l2dxJ>?<=})t8npu=)p~w#=rmpw_CNjo-XGM4|$85?t=3#u9oi7#2wCPo(sPkiX zq`oy0L#_c=HpqK>iy|#3QJ_d};xLOUjtKC37d`Fjq!(}Js+k%lXbj`#0u|;Y%`ECO zmG7jR?y2}-1#;%+G(2UEfTr*G|@T>`V?L)w( zcd1+wGnAhOv)1Nq+zwwL-4&TnO+D-u1*Wyzeb}8U3Z(FWlxE{ft zS_akBQpyGO!V4cD=v|7d9Re||R20Bt20E6y%|Iu=?jfw#zem_MBFJfOR%tDzw3e;3 zmME>Il-A;BPW-qhttVdHGd;^a_(k4o8B-SUxN3LVRssJTiifNF#?<5Ot(@LyDQOF% z*5US%|7jNJt=K_O#nInzo>g!6J9-80n`GlgUqA;+z@}$3i!@;5RiQK;Sa5Wtoq)9b z!|ak>nM#*wqNK5KW)Mon6wT6|rCAcYJn?`{Q-zy^u$q_M1ce*QzAcz$=T?zfGBFcu zE#|hyF=*cdEom2(zcVY*M;xFRCeRZDENzgGQNnd-(Y)r+adTk95GkGbSq z5~@GTqpx1C=6ImxLn)Xvhlg#U94%0p$a!m35=O zw5E)2{ZzGz-A&@ckb8H#n?&?e5&t8*+Y88D>~8d^;hIw@p&uaqe`}x@q~p+S(gKW+ zEh>9&8$A-$PTzD$WixWoBbeU#PH2Ssry0(RnATtpfzZFXha_*=L)?go#mH%3jElk4wILv){_n4ex8CeEB?GLWz zYA2#CYQk~*e6WkRWEFI88B@{{53oefS71h~|dGN?-A9V)E2-VL!ouK*n!Cp<| z47h%0avhT4TUL>4;6~k%GXX91NGMq3mXnU0v?k92ye6)t*cxhZ(MQ`CXd{v{K7COE zgg*cwI2FbzXIq1njq(nA2!+K7EqCN>AaK#ZhEd~pN3KPNIPMp4mEtxcR}HQWYhOSV zx7^1n<2Tn7tOQt;O|B6qF&=kdSn-39VmyxH(|X*9*V%Cn#n-q)jDrHaP^CuvT(cRUt(9|8YIy6s-t6;3!7sjyjNg~>8_}T(=)ogP5!mE)*0>_LHNsHesV{-< zI{G@I6Zm;2oRC1Cr5f(3LLHaFPKED!8-6|cIGhu(9@e0_Y-cqM5E0u)@+HK;&jyiP zt^90l$rqHL%`5p=_%)AG7*!F&E=FD+QG(&9L5HfA+S4KzKn6Z{p z$*TgXl+@6~2WUba$SvT@(_*>t(&B3wN`tw>5y!f83s^M$mRYFO?@dU_2PyfKl#H4l zhO}RN2Ed410-|(x}2>mE{==L2HX8W7p zL7|Q}Al(@DW0A$kp?07a>4ZCAQZvztk7Z=_+Ec+5%ZI0bFycf|yrLIcg3hGc% zoZnv!Cvd}t%w8K^xK?8mdN{Ru_a;_v!o0>XR3%yHC+u%6xE+(HDfz?r^ACuRrtggV ztsNG3fhI#unvs|mr3pkGd`Cyk-wy9KL&Dq%3mn=5Ic`8+v?X<$bLmz?N!z!OR$Flp z{Zky}o7?_pq{6|d^cSFQl%~I=qbF|#)QCzZdDA0ga*JfrJ&zpDZ{$&`^3b~GA^R-* zfnWY%swqX)!%$JjWL17Gavd_2ib;P(38cs?T5wtV8wRz=^@vY@4Sy8pMFeK4Am@b` zKg9;detBn>yFbf~vyYMojI8?*D3eOO+3d%0xf<*g%UKe^NPHTUd2EIb1)rmX^Q+sZ zqiv54_msv1 z&(AGJGN|&w7CD<&D^_}~aU7$b+2nJ3X5s=$egU#N#X3Y@;;@lOY2mT~h{aSqc@e}U zqPXPEC9l3x)Nly(lq{!NRoJ0z9e@bRl3NNdK3UzPU)i>f&}riP0EUk4 zu)FkrO?F~uy*-b&-1&Vi!&^s1MvA!7L|!bwhevZS7O47>n`2^aTY;NlSy>NMpQ1Rw z976t0&h7e8B3AYOtDK`9q0T3Qcm8F$eXCc7TLn_Gz!$&SY-Qk5a5Y#cwdh*Mkcrc= zFKFtbOLh$nt<2G-0$A~Z`E1%6iz;9~uqa)Dva0&X%TJAGU3sqQt3@6{8l_KM(lbYy z%wgY={;1u@^va=7cQYvTV-Hz+Vy%4>NTq)uXzn&3EyV~uxfM8geMVBSBf6Spla2_d zSbss}2|GceiVEbwerpI^&i&gTK{Su9eh*4%{=iSF-O@o2oZ!nOMU4ZRY>4I2kYrk9 zBhb{^q^xTmhC)cbDF`+nRW^=(A~@no8ha|t$dH*=@{f=@4qqkg+?OzTCX1MRXH!>m zG{qk0Xl$t>Fqn9xByWQr&v!APCpR;ciF&U~)cg5SA9RWOFhAYj*M}6NV>Ia7S zk~e3;c;$?fWC_bm*cstOIm^q(3}o5d!VpTrD#@b!y$i}m3_*Tf_I4xz7nV#YlNzWS zOJ0MMS0awjkSsK~&K9)HQIl6fZZ(;6Zfq~33LHG^CjDDZo!GVAo>MNRFt7|omLh!; zCQM%~?#-3}G|p$Q{AAr1s!z@b2=4ZmZ3K7 z21VPMzfjFv95996B{FgqDEfOAM6M=fRv3;C{G^59=5K@-5^ZZV%oQk30!-*UH<%h)is8=kx?q8K{u1S)mybAN&JouhJcV zLY{q?XP54PEoWu6{`6ek1mN`GsQ+KXQ&~j z+0~vPpmv#RNyhMEyM){PNH40(c2#50q(<@xg+lgM4@eq1d#;p-)HE3920Hc#Bk=$zlm>~){6Aia7(Rj6j zcmU{^0f+~H{uzLH0N87ngNQ*C1N-VIdiG{Z7k?)VP?E1VAU=dVZ z_H9X{cQ$2@g2?rVfpdd${;ZrEm2;DFZidr-3x3iUk9euO0&SF|b&kgX-z!*%S)woQVF(h`Pn#YH?0f~rD_2Y~tvKs>OO--cYk82Ort zzK(N)u0tp0mb!sPWuQ^XyYiwMfZ+83-KdJV0G}yZVN~UVL=(G#sF5}(R46G$4UJHt zq|Cs2f@FmKNG2ka3+vEMkC%OX9TE0|-Pn`HkYTTPj%{g0MsLZeJP*tkWt6M@!+CHv z86yM!h@mhxgK$}Q zRpN66&>|cemuitO6eZQ4g0rs>wsfO+#IGoSBk|?Z-6EQ^0b~)*ggFJs56gJlSO-k; z?bsOAB0mBrpZR}w3FDnvVG*A(z~npe6($fpkae1Bpc-_m?yiay12zB)cabipNHQqO z6iLnTAVJ<$VCpAw`sXu-l>neRK0~^{2v!QdVOSFbN^u+VJNA77MBYY{QXjik02H{9 z>(@NS#k}?-|YFd@R zjU>gcK!<1%%G^luSAlj>ayOEcz5>Oy2t{us`Kv%^=ajUOiLcIb1;eCFfWTgFN-}di#soe>0n*x zxbei{*nOMv*lP6!@v3waUsb5ryd5=l_`&NyxH_XF)X?a2*On=OW%-SY=>lzTZSu(t z9iGH0HP1c)wD;JCHZGR5Zv@Q^KXNbIacFjVLlUxwnE|(i&LfY@*4`wDi%x<3}c zYq2$@xK*b^UF{)nydqiRLnC@0Cm6XY1t*AC@r&2etTpL3aheP-KzpF9c7Hns{Ib9O zt)wuP;00`>37uS%Oy}$uaPZ~m=K3Ij_Dv@1V?LtUAN;_juwNpxrs!Q=X|reV&X&bf zZo<{_-$c&gajbxxv%KGs?Z3Jf``3A|hXE+V`9@)sG@C(lPqx!8T;k9Rjw7j};X-p* zG8#004BQw^p$2!K)~Rcn)+}{b9O1{uV=zc2dg9IYhIe3M5(K=iL}>k&c>j~1(MDO> zk4ATI%GGwsr^o>>L%|1MT3|A0AJmsgL{6e9A4Ng3vRX#>RI?}M~~&3A3|G} z34}Cl<&*XeiNPGnJz(swX3oBi0XDZ!ZbJ8w9?5P1%SgJ(y8+>poB=&~4?~C|e*XD_ z3@C)Gv+-dD>e}w2F7<_<@AgQ-e%&ML+P=*q)wS)?CzGJA?fk4Ca&_{~Dt?<4@6IMr zYD}B#lXIFc9+_5og3z2i+f!@;?h8iwBltd*`-zMx4MJ^@4^U#X$1 zfPA-f1VY1npa(?y7tU;LaJpyWdwO;d3sSXJXIDh0|Twd@+r9Bi?Dj$v?x+0-$DP5N1~R^axBM^jSn!XNzLET%07B%q_|A z;sIE~g%IEg-VzPXanvzq1DsW*>ulu_6bTIPB5Wu& z>v$+iyf5l5?0^EPdPYy(-;L#=lDrOIA*$Y^b{f28jRjG+7u>O%SjY3+e2p4y%jLjk z6UQgmc!z?M8m$zoQLO)+d_4-y6r~qtC|PVIdokl69zH%Bxg8*U=0E}Lg6gUr~ZtyYl=Zi?VMB2BF-Ep*G|AT+V@^e`>;Qar4h85wZO zomPdh-8HXeI&mVdwE?$u%#7*qs_iXQepw?C zAXKZh;qGk|0R)qWrF#oTL$@5+R+LwzYE8KD)J4M_=GoqOC7j%@6PoDmkSV+VTR<(n8v{Ab zOz+w)ybHo?&&10P4GiRl2GUbQ1Mnn(!B7ST3B>XPnc+fW!i>R4!vM%Jg#JN7&SYDc z$b0jN?7+b245qpwh&&2W8ESCl;{*tVjh;KaT4X_W*Oa$Z@^DkyZ&fbFnrR>~BJ60z2jw5F-T z*?^TugBj5T6||ItQ^r?7o_VA&>@mG1S|RJi0dDd0i))lf9y#1T*Oi6DwYVrtvR{wf zw!vo`6*=m1PNEhUDzOb?>C&2}WMzNjLWm3VGxXu($VYr4z8^2yGN}B#@_`|HFT-Yw zSV@)=qWLE(cFX|2fj8Sn5Vj{Y` zNm9w{?pDJpeB~Ixnt>UDRG(i|TK?87*DiBCwrecJSsG78u`K zrNi}bgzw#}->T^?(cSRnI|1;QFSGE9$`<&s4y4l>3Im2YgWJJXw4X?he;wX#xSFBdXp-4OH>s`{!#=MuDWplmIdst~5&`)YT?Y zJF{&l+v^9+_hr2gc^n7^s&R}hO^+cHGEASJr5s_Y!Jb8G5;?6-9Y91JVocNH)^X32 zf`zx9ju#RHiay_vJ$xN?gzMhABxN23T5fUm%ALj@nzAw_)Rt(qTnvl{Lf zy0?Jmy;%2(XT7PqP&ZvpD_ms1ezNXtz$i&hY=%^f zu2zAHDP3`lPBLExycdQ<@T!?47n}T2lm}m>vl?E-Nn1=6XFyrhIvcZOku|!!`P2={ zxmlW`o@@h_cuO=pmV~i}bjNGae@U*2;pB-x#RrBO2N`yRh3lLIiZ3~rc0qP3Wat2? z8BKXLWD5^BA4zpX9iYpu>|HOMmu+Iz_g7Upgb=a`5K@qmfSouAu^=9hs1ajAFAD(& z!_tz40HN&Cdw^Z~E^LD=OUFQ#-j}7bg#YJz&V4f@H?qI~%AR-ox#ynS&pr3tzF6~& za4q}X6d}9TZWAYkl3BSmfXfobvuBgP#xuvX$ke648F&yfnavnBRfa&dOehM&9ZEuw z@0r=)8Cw?lg@nCeQ&pBp)GH`MK)}q~PHw@9?@-H|Liuv4ue2%QRr}TJmql-}78{8* z%f`E}RgG^al5GWL(Oj|@)8>+u1u%~{J&s55tOyU~I|m1bI+!<)OZA@AL=prYTCAuzUNojvd5-LypS-+C^+`{O=k~>nBN@!2I(gGWoux9&w4_*BCRlS)PMumCaz<*1eRWXmd%^S@j&)VVdArXn}FlsF8MJWvwV&OByU!b&*{c zl!DFo;5rx3Ul3&Co!F!Lx)|9|=Mq;6pww~OeVH4y+2#$<2Aa!QzF8i-<&kbK$|zT# zjTa49SK_1U3SVv+@md&xQ*jw_g}&w^E#hMHQ8Eoq<3ozQB0!B7D+&8sbG)R}@lrV$ z$&`+5^~8z*jqWgbtSQ`G=?NZJM;2Zgn`7-IWE-DUddW38?7a@#pM{e;fXQ1t32J7# zm!8(DB9BgEY`jR3ei$E-Mk~9>DxU6VeIi>(+<3W?g1h|0N>J(I#>+ZUkjf7q3-4wp zbO~dj^gF4Hm8Y;acxMMf=Gk`|$BwD-)DscHcECdmLpvFsXVdwSnP`NEe2=<%2SJKW zYs%y*<2$<1gT()bEohG{s^l79JlsF4gnbr4k$7p6N?$;> zXS>&c!x!B?1%UoETtDADss2jZ?aBflkr5)Z^`~lsp~g=AmN}HUdyR7QQqNtuYb>}L zF9hz?%R;KYxpX$Oz^G!x8JN4T)1*EP)vfwJO6+SlY@bK1FiPa)HO!TTkK>E%H+R!v zVU{<4H))_-PB)!%2JEOaH=D!2e2fI4J#X$HmTtKyyd<$ zO=&3v+hnuxmjF$gUp-8WFn^SLXe*HM7Da+G_QzbO`L6ZLV^4nL*!9z&;$-+`gS`(^ zzj1yy@r%0n@Tatie`4N*pMHvy#1lNl9p~2>FC{n%lqY|3cK#yV2mZtZe2yaXXH**h z1EjK**-g)&=xA}61Iol_XA>gEtWNI}THep@^gglW{hUtklUm--#hX6r z%L}bZt_3ffldI2HrN_vdx$9^?4>v>0J3zt%ItsAQ$xKL@TdR^p)HB`uRDU5V7~ETN%sZD`TsK6%jZrLaVQY1hyWb|5smyVXlx=DUOUuzNFmDKylQ z+6Bj;Vg0N|(0Co79KA*Z+*GqY1~6}F;BNdC(Zo4?wVBO*GKQNk#$Y+cFslZ_YtG?@ z!cF$Xy*)&&mXa&`gVW>ci?ct{{3TLYUYbhGaRV9e(gdR{WWHRc_%mklb>8#nkXE;c zn%wt1lN9m3=B*gf9(5=juQZ3c5sp`xL!Af5D=_w`$He=*J)XJ==x!}$t!Zl5c@V!B z^9yfei;&TZ+WX8*v|?Ro#VbmFPG}EbC^z09x^@shvKriSC*V3`x-#`Y2keap0INMd zT2Vb9Ild~XwTFeUc5J-aT8Y*Fy+-@MoT&ef3XcNOn(D)0{r#VmNcG~S8vp%0T#tIa zN?E;?{I~ct&**~gQ4+E47m`RCbas~ooe#Hr55fy8*2BW+(e4cnWImj`TI=bInzjB# z4^YQs!)pC=!kU#%Q>_J07#;*#yEeyomfGJ$3EG3zw)1S#RGg7n)`IGOFfmadi;tIK z?|N2gZ72Fou4=xJP@_vabvZP+%;+M|)p5~%!V9n3@3N4w0oADDUf!c}w@ego4OY+Z z`dg!%We_IiK>vRrpYtsr;bQ&F(c);~CMKlg*@r`sTav(qrmSIzQxx8U~9b{9xR|Yu_Vs9b>aHX{{I=|I!LL4` zktYzrc)orCy(x)fFZXRpt#M>FogLm;B$*lk2Zm;Xgi^&E*zYYB&wP>%8;K8)N`*78 zZTs!@*oD1kKDg~kLkZs4&ODibco;o9h2eS1Bv6RGO!S60y2UrqpWb`sT~zZCg5P!I zV2RrtKK0xaj}Ug{5yH+qLfCOf2+MQ#blX~b7R_#k zO&zSyt?m(K(l8T-W~UCqD7HsSy-mYDzIxlvXRY0#S-5^iy4z#Sf;1lwpZf1+SGw$imG$(G$|qaBjnrG;W1&7h zDh`_3`7-dUgEsz#C^{@qLELL0jKm5?4>sS;=L8gHPi3{UYMIks`zSh9-D~xVcF-@b zj#xV;xIL3lhnDSdGN6ZLOm6DTEjM={tv={vSv`}kM#PK2v4EGv7E^DcaP@OdBcOb# zL*52rz&heuA%9S<1j0M(fH7@a6 z$4`ISN9Xtz_-TJ$M#WyfCxMzde39pmxFg=cnt!$DCi1>!1j_6zN}%wovb z77mKMfw;pSH_88vhs$3DnEgs+%nR{OP{VE|c$b&ps6F!JGDUZij{>sm{f&Xj*z7mh zZ)Oj?6BRe#O{^#~0-4UN%G%|(QT*n6%)c@=lz6D@KtWOBcTa}b4Wrtx>+ z;@+9-IvnD2d_+N2F&9{7nH&IF8{HhMl@BG^zwm6@)5K%+9h$%XsWLrE<2?r6+Jjq# za;T2?wZc|;Slub|XtA=cy9O&^b*1O_?d22)F?B@M5p2zF-d|ah9l3ly0C_Jdv0G~l zcFR84)yU@|t4!0xG0uWjk*zeP^er~3pq%4!y?x{AH>~f?ei4O2HN_Sb|Op&erDX)ZYP{`GR#$8+Ob-colG+nF)A4J+g4utN2)# zWBJjlnd~9*$&ME^=#FK_H(+j(T#l+Wn{>{38`5GfKBxoIuUj>jI|Q`c=dBW`CX&0we#MnB$kOJa65XV>pLo1%hrJF3fwTY0p$^ z5{UtyU2g?0q+7=4E-eVi5y#v2yQDhwly28;SuCYkvjp3Las8Ugau`);#4258Vxx}hD+VK(z<>7 z%ov*Aw-3!n1oWe=mWvkaDE>M$8Lu1W*+tY3uglN=BiZ$#B)66)m`KDZP4urrmz9Gs z+LQp;zj;3~N`1E}`+-sqbnWlq?F$OfcX?^86`&8Wr2&;-?LOCBjCCMbjm6MEsQfH~ z1j zt?qZYhMCK~!+GP*F)Iz-Vl4^%^YI_|yqkaH1!>i7OkCb&^dzOrIf(>96H;n*zK-2e|z8 zVFgipSOKkemS3f>BSNymsGXj#6gMX^N{5QEJ|tgvh`62ZdI;7d9A#R?)}2=q6wCE84@uG;Xy9Rof(}wh#>&z5=G){O}bvjA`P~ z=vpY>7Dhmg%CkT8kxs)YLspqLR5{b$@^q*e50^6ZynTbyr|AaHK6)nHK_81}Xmv{7 zpA`?el(xA0f=QZEmdAA%U2dzLWND>xPnnlk{dEq_^EM)T^GaZl6^i!Z4%^xKX^*40 zd3!xw89M*iKxwGz&+n`MJb=!30$vD!LrlhkRl%Nb9&N=AwB+-RiK+FJ;845w?CW^y z=0y%a@$1MXpP;W?JbbvbczMTSICr`D+(xfr?VNxv3dQ%Kl5%o5E)_KD74}`;-xHTu zRP7t&B9hP1r5;8TsL@Ti(L`C^{5dHihgDvjdOt^c#)heWP{RtMuLC-8h;94Y`~(<< zxowoX)L0X_u+l#gB4MRZVdk2jOyc=nL|gByC^3sF#jq8mELuVO8Nta3yu-$eR)t6& z&N7Sjf`Y?%3^2|YPOD-{>NLq~b;xQMtHZPmRjNGwj|^4^O8!%Uh1gzen7moyk5)b_ zUQ5zYaS#=gp>t3X3G&g$(y6Oj<&|%F<^ij7XdxY~`~%@aK=HpUa#-mkiwI6t^qOjOqzBkoI-rJnfOs|S|VtH^O97lu(jc`s0ga(zGt-63m zD{9jVGb{}|oRSgrYF8-RIzOH(TL+*56cx_(q2f#!KpKZq2HE=*s*SV0OnKiu1_8Lws1yGp>BPrRlE`+@}OCN42Jbo?3s&5m8o<0(7*B$GR0m4_iIcV25{1ZR(} z=Js(hHd!(~u^mtu-_9LYFJ5gel1(aSR2gr64Ktk4#2QBokJ{;;>)64Fj2Rvf<*OtF zn;lJA7~%wo<|BhQNBEXE->C;Ar6cs~%&iZ%IyUlLPf3bfSck)T5+0f{H!R#w9M=lJ z7xTND-!VkkaQFTU96rIPIL*|_x97A-^RX3mJloQhWc?rZdt zs{K~Q1%Fi@L{bKMUQkdzJR)F~uwsaL8&VOtVq?kod`WohYwlO%JzsW5g3kVf(AgGM ziigHW4<8-|AHjxoZdq8<g$dF0-qhYmC}XJNUn9U!fnF?2Wg`>HGPUco1>vB=EdF$HK%q zn?TW6zG6Ji-KSA z+emS*=Lcgp_2UD6{e=HFep`OdC#wE4ghe0Dzqs*lW~^vnsB`g3qfNco#vlwY%fw1L zY*gVT9HOZMsOgU!+)qb*yg=+!H`N6@JG4_BttGTp2B#DGajD!JpXD&(wful+4<{aJ zAG`K+$!g6sG=j-!`5WNlBivD*q`dTGi0ZedtM6k0<%|t*bogOdo9NFpzX3YB%++d@ zVR(y14b-amNp~I_kbj+xV8sZ=+A}xLY0_M2f2aiVyP6OJ8cCmx!C*r4Yti z#>N*=1^PRLyx+Rx=xB8)sr#OtvguLvO8|g>G^QBgzLHvbBA(aT=0nHmUV5-1d-HD3 zKR#nA-6H@QW(ej~m&*RU@Z>I(8kyoeL2)KlH2ZPU)MmlS#nqUHlwVLvt#kgBvT4n{ zI#ydo|3+aoqe8Z2`Tw@<#}m~inEy?AO&KkCE4%t-z)x|y`B}`3<;gN@1$Br@_w;?+ zC0Zm<7Zx`=Ibx=eC3tP&kzQDe6Dyj(bCg7;T|o7l5e9eaZ^CrG3pi!n&haefUTpI5 zHs`3R=v6!GjdMh?nU6(TSx;10{2o0FX7irGv9P63gKQ+*gA<)ubEy{1LPye=w#=x0 zolF)btL!aNx2I@4YBNq-8;W#(N#)v^rp_~q{JQyRsA5rI=bjpdhWM@LrP<=%B=FLoI2Yb;deAYnpEm6epm5(D!-5N>*~VJkMS(k1&}U)bV0Z-)=Sdd zF5Nj@2=aD~^MjGwbtbe3Lp#>PdB_=|n%3 zML(@W;YrwEWrHy*CqBEib#Sb;OUwI|mbca~oV`-1NN%6n^44;q<$YSqTMG-CoC{r( zllab0qF_60zWX(yHfyLDD()%#Zs9i&NXh0QRr_KTueT|v`5WS+;FqtD?h|IW_0_xu z64BN|LrsBhrTeX=(>F;cJ3CGpNg4-?(op>7o4@DF)FQ*S3(a53V>rMab$os&zZHEG zxU!GVH)X`5jtfWi#_M5*)(ZWPGDZweZA-jrZpCHTuPExCUnt^=qVMBjLq-!>!Px+q z!?T{f6Fik-`8#yoCY&a13p#Tf_1sQI+qME75;J80R?0-VyC(Xx&Ho{^gtoo_TxFlL zWw2nz4POCQe!ji_USCA!DkW46l`Wkfgc4>`*<~sd&FDNDxzPLrK1`abj6MG)`-*(_ z^~8B2U|2iiQn?FzSidAuBaeG}g^TE427mORO}mbcp9r1n=5 zjl2*P$H(c7UStlR^4T2RuBORaSdRzKT9HQz-L%KKTmv=OyJOi zX4Jh2s-!F92SQ)}DsDB+{&$F@g`###!xPC;BfJ@rN(*_c{sC7kE`0~GMpt{m>d$pW!=Y_ zRo2g}7|61f;_Q70-8X*IpSn`p(cqH~wmd4Yc#vcviM~^Z+3H^_A9;%Ub2qH$;dI1N9`j(F=*83zK-`pqAQx3&&NZ5+}Qg$PrX&bmz7G z^gzSARO+h~cJ4R~#L~LiFMrS#?lvKgEV$uc_GFjkBw%ih9ja<*)#G6$zpxniCDrmm)3T9Rhz z4&Ax>P@G;sgm~YWmaY~~#7|RZ*oFhdsJ7AaXI#cq3P~*+5lxXj? zypAK?PSOpLSL}I}r_948OsA)mf zUy!VR3^AYJF|&&Kl2%Ms&{5NZRz&Rjm64g&F6&2=Y(>f1ehwd2Le%UCQM(g$kvP($SqJp>#LY~tMMen5sHP_xCu%;1ngzfjLDDA! z36he`^zsnNo4i7YUuOA(AlY1Fj;uS@nj_Z~PE_4DiOrp}9$a~rMM>4k9jfkY#E4ep zu_oX6Udz$=8P;NLDciUo=sfl^NYkBbT!&}jcMCdpw>5xnaZ2aVEI%+1Jsbm(;40xi zzCJLtW2`8|BQ<^kYK%c&g&MVWtKwF_f?ohB#fd6V-1t#a6xNgZ)U)X?kA&WuSJW?t zr|*-l(g}*XtS65txT@+XbyyoR(~UK%I<&K)aQgyMhYW^V8K@CAewgIqjc@BQ#7x`Z zNmU%N@aH=~D`K6~33a5n@e6>mtvC`1toOu?i-=kMny5h|Jt%P}O%6c0MVS4?T%Bt! zU|jr~k45z!Pj4f8DQVC_NLAgEqEjJ86d!F7xfX11x&)0z7I0?K+V+M9J%~hs6CZrH^wTr z-VQn2pkc3{#DT1eQ$5TL2DRLUwiEbkmd%`7=`tM%Lux&UvL^Vanmv6l`Zd)AqA(l z+cp8s-Y%4 z&@Giz`WUaQY#~bJ%IUjnh-<7SZz~$(UkFKJe?D3|VI!2kmBf0zl4pCYMpB*rXc+%) zWF@dxB|YR@qvcPKgeTc@DBJub)~th`O%E11aJAU%CL5m;U;un6X9{c)dNmA;*l3*k z2ZC>m)X-F;PLIg=1u^tMW_83Ny*NfA$ths!JaH3^w~(86&3-+m*eH+LM3n1WQD}|^ za&!-z9Ic{nGIJ@K%34d9tR6@6seT#+BF3!eU?K^V1V(5?uWls5n?4i@iSH!I_rbhUu+v`0J$;0F7 zq!3GZn2Xha0-eS`>+>)A{3{kFrX!Kb}E+Hbmlp_k}VB z7n?7ZX*^PO{dSx5j%x=|JSOlusO^ELljn`R*^3GdPHsM>TByq_s$PmweGmvxA3h|?fm*(C8k~4h0Q0lh2D;qHuFu zeme{s=^>M|a?f^mBake&x2yo>j+mQh9?$$&CmsLOZxAu?)b!MslG=uQv*00c=3y2* zRDAO=3mz)Id6?xgFGZzq`(0B~lxAe)nflmCIbmh2^zFFIs#H5#(cI;CIee;~Lu=y6 zJu@ps4wxj+AsPBjv>T1-nuXOGltaA|60l-XLY{E$jjCF!#M@(-$#5mk@C?RwhAiF* zDcU)P=IUNtUnY<3V^@D}hx@ZPi|qVJ<5gr0g)N7flNI)8)ho%VJd>%+6>Ddqd|9Yx zDpM#mgDh%pbD7FOv9>X)+D674BT*GiGm1w@Pc&A&uUv7ZTO1V4h4)hj;V-J5OGssI z^VVQ1PFI7i8#P28Ixvl1bBi~n=V?5}9A}AIJFz_Aab0VY8ids}11&EBe#6QnPgKI6 z7g-l#<*ME=wI(2$%~g69rQAu~Y;gApncU#+lScz3ScoZdWyiJ|2 z3~L#KyZvg)(B$P_Z(}qJUe=;zs9)|@)40LAsJD%=q-lVobn*Qa=A*&2aw@A`C4rZB zdG+5Id5RU}!sN65n##8A=G9$cX<(7MuOXiK^$brFds$|DcWr8?q$c$p8r@K<=sSNd2 zPVGUA)b)Io?n+={I+)?(XW>#>KE*w;C1Mz8=|qwwy*-P#(`K8> zP8C-}EbU$M&Y8-Vzj!LoVU-0iTl-A68jDqfbvYTQ!(__jBinc@&QWInzayitc$a<#9~V%Hmu-BA7}kbNaf6!2;O=&S-0{@? zlQCiL^dyBQ4XJ3>P~zinWoj0th(l&jvw;av-AmKeByR?KNAOW?%wF0KZG0G9HrCF` zHvSF^Tp<}fxuLmQzB0V+RS?U%9o_V<+9R^# zmojjA#+Q4>{qT1Fo^Z*eBc5~)-EMYU*78T`N&B@L8!P&A>vGjslLN2U@Y?UNs2f_R_dh|QTsCO^X9FsX)Ll-wDg(dd~8A-GI{rt zgAm1N`CLgusPx%fS?e0&$bglC=2Y(1`wYrjhv|+d)E6cjl-R!Y)9K_9O{IAmWR_Y9z_As5>_vAu<@R7tAPcslrQg~0^xPh~Nw5taugF>;=~ z`DvUV-AgZPbwHwBplA;vv!R}XF^imp+u@2i-bc;#bf(YO`O*r~1@ZE$ zh?ieQy!lX*sQE3SGt;kCJYAEtW20=Rf=bnI8k~Inx!)9 zGRZ8J@0_Hv>#{aUHQ&*K#k#N_;Pf5@r(?D&bizp{yXHGva9AduOM>%lXEUYUe z2%%x2W7;gPD>_E+0#YYWyYt9HW5Zb|c$eiw(D=*uU>5o5PhHvUwELod=Bu-se5xP! z{%C8_hatrg;D$uz;hU) z=xNcDMVdpxP?29vGK0~dUYB+t{h1uc`)x2HC}2dFLxSmE*WCd|HEX!^=eV_OV0fvA zT>A6-2ihkEyeyRUGlNoovPIKg==C#x|HCh#ooGtmfCGlvLDR29<2TS%*v9l$1}amP z6Kq{neGn;mpJ@Eogbh{tM=EPJcmQkdB2z4VKt!E<<6Y+5x#&G5Gz0gsHowY8fPx^w znhFmZ>umkCkPZL`_h;`T8*5kR8Xr^Vb)z>wG~LuZms!A z$FVoHa9x69HnsTZ1jnvaKRAlFG*sjz%WtXl`!gHMMSF$P-=L&aJ*f;$nRA&HVW%DG ztp_#6*a)uHC;Sc<$HIuCLLDxSh26=utag>P9Lm4t5U|jGPI4197n;uD&kj(Oc&ayY zZglhSl^^qmnRi6hHxn({1Ye-p$hM+f?N_E z{c$F>5n4V1S`KjOv}(IZZl(w#dRpxJVZO;MHK{d6+R{8}bsElrJQ3R5NvcHEw}7t+ z8Y#_*i1y&Gv!I3b=6e=Kz`(v)oiBY}&ox@++djq`NjA zRX+wEusLNEbMf>V*piBcx}PWE9PBNRmgIDgwjt7Lm)CB?0zLDr zWuBjWmev~IZLc-r#?#3&ZakB3^<8|d4&v1NCrbEypxFKMKn*)IINxR*iQsk9wa&w6(bUK~UJ3vjq@rI)TWS z8+X(Ak`nf^36*!WE{>}oCpMO>S<>}UX#OeFH5cCuoa;okS|<%l<4`ATUISov8$c zJWCT#S@5?`0|B#?V66I4p;8rxWD(SY&7VZFzW6Y3ibc0kk7}U2VeNIe?m$`U*wu6c zs~T%}XwilLxXNn;ui>lhc8Z!Uvg+1)z5IS}*zy{_H+kufi;|;CJ3!HX<$eL*K?o=B zr0kn!l0L0Y82alBjD|_@ayc5~xn$!;KVa>fhj;_$_{IAS)1n@ytj?-8qR~gBfbr7dMBwkE@?{*gP)u`cmtvOo zPUxRQyw3$QasNwj|64FW8_a)|c{x?C04hiZL#cTSyulIQS^(fvDnPfGExjU`#rL$E zpywVN3%)?Cy55!h2A1Vd(FDK{LxcV?+^*nPZG(^CRpl zO7ADPT9Sm+3@(b`@~@MrZsx|Tz(apXiGE9IOgO6feOX<8^T)Ct;%JskzNDa*fMD~h zat<}WW(iIL^Zmt*(NL9%F?-Lb+L5nY9+=8sX4{&sZu$y)8T-4J`M-5N&GlF+|Him6 zhJkR&yEW#U|LO7vFGD15d>g0Zcm$*zr=6)hvSeCI38&}(?{I31n61Xi{8!-=@K_Oo zwulvqn8jPy6SoQ)sf26mio}#wPG=8^63agOFB+ZJ;-=eWH#~S5x zS*whk7aXx_(#NJl@TQRdm+kZoMIxdOU<=qS zvnrvbS+wPcLqb1uOUC^}#6`5^Xu7yE%f7&OTrTjb&De8Dez-kxa7F#GJT)I*xcIu(DG-H zj$20fBimCeFTIsGx#wR*%kMb<%F`y|@<8=hhQH(hA4$h}+F|ft{tVHInR-5x9cX+3 zI~p&BYh5FDe7fb+3@w@ZQCZG&eo9#5-}!K&br(hwKMG;F>aX$LxPMXyIiFL6`fw(@ z^ixnoF!&{EGvDK5d8D~9-LpTH-+D3d(%7lv_`;Y}aOoSLL+K9!2^>L)7Xo zh}xfROU3r{ntOk~c04zBa^+H?!8S-paDAt+INzVomhz3y3$IX66vh!P7hc((=tt4^ zC-?W15QXM3ZxBG9GnD#LQo$2?EbyjBlfv~-xXCGG!bCJHP!e6oN4!-2ACpuW9&0B4QGx#zXAa93to<4|;7!P^P{%JF<#) zQb?7r_ZAkT>Q9Kj?Ra!EDAwqzSorF$@wKdmpg$(K5oNE6uCF|J`ubGI$mWd)>F!&X9FYDx4x;SXyJJ!~KQCk}uHI9#Sd{E=~`Y3NF!% zIKcBMoR^}MCupX`VoPmk`uL?!w1V=S4-b_JHw;eGH*Of@TzK7dk}OxhB#72t;Nrs! zNhU8~!($#{nqs~(FtZ*Qo61Xzq{~15Z0gE7x#wIM-?3Rzc?{kyu-UDu*nDN%<||Rx zHvP~%SMwhNpy>GIN(HXSnSzK?j;KOi`u!>KZ920(Xe^P$pI&g9j?!q9d~`XM5CDsn%3 zf^mbmo(P*~4h1o8Xe^*QUPQ3Ni)~^krSbf3hv&J(%j0+1Y!a~`bowYL^U`zLzT>HJ z6|A32D_mQIw!dzNjcuP|K#Ln1M{W?Xxdd3LP+puHEamyGE#*k{##WHegSHYc71>yQ zvlUXHaoz_|x=z?RcXlrgoR9zx;@hVw0}|iZ5im#6`npoSvSxASsHL~JLQ45zMeXod zJ5>D8&9O{;MqvovrbA{r*UZ(X)jXur4aL~gbAX8kaC zW0v+=I&}k2mp>?7vDD2a$W^04Wo&W2)W-x;+Mh42tNuU}L#Z@*7EBS1V{7;^si&I! zIIyxmE}Cig(Yk0RNBg3gT%8xq%+2cGOcr?B!%TiG9+wmhXS^l@P&)~N&yY2fio(U^ zihZ{;(ENcCutmBXGi;Fnqg|0LD$Qc|Wgf%0`V7WUt*0&(L|gyrw#jnKb%-@!RQmciKXuB$35BdSxWU2LiPTH05#6R!TsI`GjX$) zEk5=J>ZX@Pl?C1xA5?{&1|w2#)G0Q8nnY@xFIbu*3T^8`<6?YG?V{g;ntH?j!BX~d z1%@|n2Ip8HBo{t9vRG{XC(zkebK73Vk7Nuqe~6)Z&-W)^Og-#`u0b^to`YY08rf8- z=Bxw`egqPzFj;;%?v9WsTE1nqkIvIFsn-MJnTJ`^Ri{be6m9&BqJoCi&5BT~GdE2U zUfU6^2uHc=az8k!x~X%c6`>8c+jbo$M_r?eS_Xk7$>T$qfCoo&{YRy_ZnUbKes&)u{FjmFhc;m*; zAuYQXHLBQJvG_!*V~Xq@Ik@nUwQR>H-MTxcKH0G+J$R3kPNeoKC({e-h^=yVmoF`?`K3g#M@s5u;L>4Z89*!ok!JNCoY3Vc3fe&?E(W;hcHeW+;Z1NLyd zd|tcsj;q$%39c_VknEwt`qiAG;cRDW?eDK4?ZiRt$E(bE@ajyu7k{Gnkeqd<`tdO3 zLwmK3lN+#Z)ap13*2TEm^rjZ-y4M@qUP1l#P-TZmIiXI@=R<(gUDRb^yP_ zN3tNVo*YMLaN{__g($N@bT(+jgrE+zq=tM-SGYuws8*BEer zoomP%{BNiZ2LEf^nv5Gav-o(H=+XEKB1kApNZUbk;|%I7Zd`!>);Cj4SzB_B%^jb$ zH4|;*1a_C&Ha0HdBl)At%(PZr8}j&5YqJx!e69Rudqa|tQT6M5xxYQs;3ZceXqgGy zWGKWN+hNgaxop`Y_!0zxC92J|;c>L_M?PoJ7|SoOfIYJwG>Uh@5)&nJu=k zEUg0hAc6E)4he^dnSj-j-xo5~8rE(&49RKTx7v-maXDeOy<^91m>i#Pyc@rKsG2+7 zE@T>JA8Nb@do7Rz`=!Yd4}bz=#eXn)uGe3klz%5-a%Xj zlkP3aIMG?seB*5dFU~hq;;bPoc%u%_J<5r{pX>R!@!mmy6>3O_XpZ#Nvb4nS9~{pmjv~lIjeYw zI=Fii3stSzhvs_N%PA+T{{+9)!L8=uJPhzuA}wew5#k`;Xt4O{u(g?KxUrMS zQez7`vf572iCXS7l8ei1JnZJO_o7y$UHvtyy=AQT?mVz zHCt;{teuSX1;}hXSFLTpb~iTfXwZ5NZ8@s`2GqIV6UCF14S`mlmktvyQP0Vzp~erG ztm=K&W;`C-u6aN*mWx&PT;&m0$H|^~Y-U?j-GH^bHcPL~+7k>tnOr&Fc!(93`^$9b zf|W8`SST`K{-D*?vgOU60r#}&Rec_C(-~MhBd5@>t|0Y|#z%!AWf`nV_mmfV$)q18 z8KunPCJgN41;s`Z9HF8??Yt?XUDCJ~m>;T>MJbvkxZ? zryDIA)*d985EZc}&C=@Kpo%m^u0_9zbmoG@w@t^)#0Bt*FI|)7+m}9&s&ApfMAuJ~ z*I$xXz)pRzXhcnN%=W^GPSf!Ev#5z$+?38@Lj_4IM>eWPTfJ>Rb0(zC3PBf4@lHx*h6Pi(rm`?fqYfk+nEj@>c`Nq1wD%#<%-4&4@@^M#JBMj z3)=e6fZ*^UYp0>zXRMaNh2-8}#^!kFLlpHR2-;c*{wI=b+&|uV)Ddv; z2rLM-FbuMOf0gQeU9x9CCH3LoIJ;i-ga061`p8xuSddi&J>N-JKfAMZ-6&R3-?men zo+zEm=Z%(0dE2UgI#~)GW$*R$g{+rcb?UN-XQ$R(lHhw{st0>9pzzA)6qpJYc4;(JBYPL+`(4y z9g$AR)@D}+SI30Z&Dy?gIyLD5u*r11orpe|K*8kgffv@j^dv>JDT~WL;*TXdd#aOG zLh->)r4Qdi`2w*eVp|+w$g;`&8AO{xVUqDGy*8e$qT~bTYRJUTLsE(8F!QTKwTn6c z49!h2e|Lc3D9XhHJfXuvS&3)R0mhMDehcxtbI6smp3U&kW!aX8jlajc7X~*A;SaPZ zlAEx$R)OJcvr`Attv`)cLRK~=-^)a64o$&1moIL-2RjFt8TgZ#aDdrC1}XJ1qCAUy zoq#UEF&TK1uT5Q7khWXrFW$}s{9^T$#UkyVSGpEy*FT^R>VuJ%1XfrE3Qep-J+;Ri zK(K?OI2)kNyse!Pk~~xRdeH@^Mf)~7Ul)Ac+IPDOtzFttdKd79tOX{>}*VK;V)URDcv7*;8_QQ>~Nn->=7Uzq^QQlMkPR46IV-9f0cx}=sj?CQc&j%EI z+9;IRkBFqMB2*T%PR%fG8u`Z`eNS)HwaC(mNz!C=ckb~0AO zUIQNP;{&)5!{|&ALnQ4IcQv#>!{>nx;W6zL^6?ZQzAY20?ew;rDl2&lr1EXZtJV=u zo*|!BMBDRu-hE!XM|%VG^)`%%pRdioxMW#Fa z5mdVK^ry~;M<+p=RbpP%?}|eA@sdiPn8x9WqMh=06n}p%>ql_m$RLbeTT;FE^Rom5 z3{7&+=f60$4LmtWOXi2;pe_3=#@rK6V{)nD400L`1+ju$6_ov4&U9Ezp6ipKf2A5g z&q3+Te|Io~*sq<6^|a!6w`Ovi(07N0%5DiXSW%Fz2^N@rn)7wq zRX%BBDfdm=x+2zK)l$lvctV7EJhj%8Xd353rZ31G<^F<8sB>m-lil<&1v3|?M^K9^ zsrbd|wWSPavxO4Ol`|zVKg1JW6eJ3u)(OIpG70yM0kdu& zm_sob_XRP#I6buVNdT0(pZ{pc-65mkP{PWsZ8*rzj3Acf2d&J6RAwTf^SrjyW2rE; zxs=V0E|xO$3!5e)x0SN<3r)%NC6axcyO(OGw`$U8>OsT|YcDpCy<6Tw5A*U-jIM~? z!?o>XUPEg_O`*@sYOF7qFf3Gve#A7*?00i_KUz-YvAcgT#4HDMD44@;t|msml&x5@ z(NeiIZ2CLAO(0~au3B1OE|sfaW>>^Bk?XNmX&L=Tm5xI3@0wC+85VxFe?w_Qsb5+w zY_pGJPet%E8uns=6$Kl% zf;FxonxB`JdY@O?a68X@vJ+>5FP!rih*lw>iIAfN;(Q#+q#i<5zLfr~y`~u3mDyQ# z6WXXD=P`BeGH(#D(@xs~c=gMIZtQl()i<@OJmxln$w4>%n+{)I-pRL^O;=B$Vz%JL zLcu`Ko%vN9hXnSg7BH?QkxNhBD1zqXz+2KHEI)mkKbM1;QK7u_urqit2UXO0e-Nis z7+!k1d(oK_KYu01hNfXBveYD(hmFsHrcbFA8M{IY8i{z*>&wgB0kaXNk&`8ln8#jH z?42u?@xRhxNPN1EjwV8WB$jjJ$8=`Za?ZLX=&ATk;-N0;KqNdTglHlsT` z)t#Ht3&4%Rp4ua^vRuC=YYXE#XAfE+4^78XInqw{uYBW zNk1aXUHiM25bS!rgIN)<XPOq3i@>bo^Gb` zMyqv3M%;{KL@P3E5^u)xNH?=)@E~Iji|$dUZ4Lhl#ul{KD{w_2v!<0!X(qbELfrsN zSe%I-Nz5pAi$AuaU|VPx_vdoHkY}Xy_3wt%)cL-K*Wjr6J(fp?I#lM4 z$ifWQI6IuX`eFnl%ia6WMD=|uR>IFRFHz+oP({ZqlI;m`aA&bOaP>8{ z4mGjjkp9!itlEA93LPCYuSjR0+#fUH%aPaze4mp`;G%sWYo2#46C+EXPqv0X4kYB)>{fghSLNznBHA30F_kf7#eKpag6mb9v@Ao_ml3Ba zYw#HzE}KsHW)VNCr3%}qc-RPNkS1Dai{hi+YIKz+xOJVGOxj$}UJ+hp%MV_eCv5Zs z+(UBJ-jy*!PU8+-jRh&!^71HdSGL zg#K{X&m`a2v-aejR4{l6aek+q-7zw<{CiwRmQZS~sn{L6E`43q)3`G=64$AncELhI zG<>6HO_v@;99?>pY4JeS`Z9Mn#G9ZkL{oXAd$IP&aX)9BHv_+?b}8=ybuaw| zw2geZ>B68@mUf)-nzHe!nYdmr*rl!hH2h9<=D=5Bd0qTkp}2owql1(p4go%;b7yRQS^dYZN*etqU42SiKeh!W zdjJ5ho>qkjnkvL_Q^l#b_2Fsrv{~?2n|PQ7kCHs5?aFo2>`BiiY+VxBEO_)M9%e~m zE+sQs(z*tT#soj0*zM^~zQW18bv@K93_1#EY!JqYW31C*!%-3<21qN~xE#ns3qWk7 zZUx!onIy7ll`+)fr5lXo9m(D!*BMEm&lsIg3{B~L7Tz#H6 zm$uv-OJhfe!Jxx(V+&FYXc@P&)hRBD7>l#U*{WG8J@ZM%#^*FgZJw7#D2Ga8{OHEt z2%oYA9vJi{f|8ukjTS}@!Scb=XyjZ()Q*pk|>q;gx zldB(9B1AZwz>6FzkU8K3qz4y+f6L+`F}y~UNI&grjpXV22-{y5dupgaHMTxMat42i zTfrj(Rj-6nCfM*XsTC2bEq)RZUZ1ZIrzaY36zSTeoHzJ_Q06MF`LlPD+m~!=BipF4 zSJOs#RCB>tdQvlrc*WuZx=j9u28!yjO{RJ@J26C*WSLX_xawl=?#L?5Whz#HZw-=S-Mwxn)WB1YXKjs&N+HVd%S*e&&#~WAnta;Y>Gn z)w4qbv@UOUI54cH$3k#|oQ1c6v~YQNz{TlFMJr=?Fr~ASt1@bhUiw z$V`++DUl{hvs}*0RCs7xEwgcdNQC-M=$=j?2b_A1%}c@q;xDL>zS{Rxw6y;Kk!XdZ zqjX~jf;2`ESk2?2OeQ-$Y-VP=P^Je$Y08LYc1?j9_aKl0 z#ytS`oQ~dV-~!tjdT=)R)hu)elMftuWX_J`?L)@8E)H&-N`-_<%8&D56HT_vhm5iA z5Ud+>RbOI}ifC@HE_Z7-?+ll_>6Ir^PR*4}C%RSeiu~tL0$kq^t;h#8>pVOqUwZZX zTD>}C^$0-K2hs-~)Kw*M`G`K)AjmFcX9S&rdy6x(Fm<>JA<2m~Aram^ue&hAR>7OVdt6^d3b3rCLg)MrsnW?!+yW{X#p`lJX;wTSV17!0yQOclqg;2sjkT2Lmr#-s`J_$?2sJwvtUR{hqb}R(Bk*BNsmR^}=Vtq>mzZv;u z4gl;#Ya#$XD;&ECA1bJ^qb08ZRFe3@9U1#FY748-ArRlXXb&(HtkI< zaC%2X12b*>R54R>V`r{l*m{1FwhvFXeEKf=ct89ybf73d69DfEom5gU4V~19dy2;1 zkW~HK$**Zm6@?4|*_&-~u0KTkszuYNHvPD<7m#xo(!)y|?#Dr99)@wNf^W|cFP(0_ zXjW8otM=RTqf2L*FNfQ$VI>3|6%sJrSdg*`K^$!(bg%??bhx(^72W-Erd{lF_y{fCJaw z++t6FP4&aPlXr(U`tUeghc^1I*q)WZ7dE?k)f6TP%ph1WLN{OH{cpu zz^1Zk`t$M9$e` zS$R}s3rOZ`?U#0ITrf)C`-ja`FGqUV%w9NXJ#6Ot#Iwi?hF>XiEe5b{Pl$Qy)>=~X zP+t*^pKVka?xM=31`Gf_LFei_VMGH*`_7339`A|Xn>6B~Uq%}JMaw6O6yu_i@8yn` zb+CD?jIri%GJ-PL<1J*dd7ofT${cRiWW);2|)2YdhcS2Rh#87rIf6MpS};wQ+Ow7qRGQ5Y5vyz^_NWB&L{ zAs=?Lh$^PFp#7a7S%k)Y$q_cupPs_yr%x)XO*Mhv8m*`vyJNrNI&RO$`JS!ZL~<#x z6j_gr(gC%+vh}r??z$>lmdNv|9>7q}>Bua;QXQL}Ixep_pH8A8rbfn!=x}4!IDBswV@2_d@-)t@C%0gj=&ZKI70vV*8a}rcKbGCarNIYGDo0 zYHMh^KS6gBuT81mhUehdo~HzCWZ*k{CHVbHuO#O?2m1ms@2UoeGoO_r-@$yAJ7EFC z|22SaY~lRo$js-EyGZSgp!SGpMTB4g@b+cQOz&f5hkdAU71?n>ucSv1FS-L4<3*d> z!TkT=Mc)v((E0yUE_6V91QB#+MO!^~u%cs=rYg_mdB48;2Z+9!H*IxfylL4I-n9DT zLA>elkk>G44R0)pW|W?{Tw4rk`FAp?NuY*T83X>jV$E}eE}sOsfe<5Z?4V9VAOnhe zD$iK*ZD`Aw9g`wv8(mg3;+Qq(qYoR?34^HJL;d6gGH<u9`YwwP9irsab?bnXchceD%b{0b>>#IQ2Pp;eozoJC-e!ldI}vlk-a>U z9A$N@^>mTGL$2}{oF7A;c)0O?8RP5TlVb0|+xJPc;Kx3X zd&!Q_I>ZgCTv}sPS)Er>H;I-8Tf3!G?)VFsiD}a=l_r$px&D76rrSs8*Ucc z=4tP9Tpwf_8;XK(<|eI_cjXsUAU_#JfduViPT;W zMfq?LFEII_ZX$1^OgMB@0IEpb&$~f8o_f!L@!H+jG03}&I7>LL54KOu`|qC&Ao;e6 z2`-_#j*07%l}ZbxkQF!D^1i^m6M$_@G_rt+1W%$tOz` zE|aZZqU2rSM54=qD$oGrzNRpR!x#7hi7>!St5|mKzItuLiz}SKn_s!p$eV_WL6qdV z%__AvlK1!RO;?3ggLGARMX4+Y5?+2@L5E&L9d>Obtn5@@Jse4QxvdrFD$}jyk~~>6 zbwhyr(*{p@^dIf2VBRm2A$Z@uVdq1GU&rG{j^0c1*-bmPCMw8Za#VTWcg%LkK+5G z*P@?w4~OorOQjzC2<#U>c4^n{M=UGG6T7=o^AzaVOD|4+mP-#3Q#;`n{nT&j!**2nM@k7*mY{VAPFAxMxK!_8Jdbu1C) zFqMSGE(*fY#WlrjYRbMR+qb*>r}%8J?{v4~%=HNV1N&va!oFV| zP^!$Jd_HR5|0*l54-V;j^RT`z7}fW#<34pyR0^}XyoeHSkfgfBnj&WB`E ze|*SK_#S()p#8dtw^|E+!hXy5xR23dTp^z;?fWSEKEb}vx9{CoDEB{@efdhof0cc=K1}eBK1Sb%n*ExG zsV<&s_S^0Ie*6B)zL!2+X&<;<-}_yyR1dW8f_;Bx-}Fv}p1!lbGn;zk&dc~d&%S@S zMs;!dweo-Xb&B)O>uxBh#d>>H&wMJPpBs59F@qgnT;~T@oa!3yOD*sob%DN1IId?C z)`zP=+&*p~)l9)b8Ss+Np%C|1LRUl?c^nu*I@fp>a%>W!_`IDFK}gW-C(ZY zo9p`2vO!68DeRGGUr`R-T_Y&Cydm{;bDdSl9YVPTI&BLjDzQjf+p zg2eYr%=Mh$dbzn?8Cu-YVHRk$AaJ}AKUka`_Sq?wKl>z2ktVDmrCH?>JH&;*O zt~)K}Fs=+?A2ipo=6YJ{6Xu%6^(e~oDRZ4=u4kw2BEP=W#TN6qsV|`)zAv>sxb~at z(NQznz@40LLdQPt%{HS9uDi|kK3va8Jume=bA2Vaer7QLi0dZ8eq&)Jr1bB@NXX46 zpp4e`%>lf@5$klsfSv+V{!H3y28R{ z)7#R0l=ac(x&qfHa6J|%yoro!1lJQS-E(nea6Q>v`^@!|)N9Rko4J0=O=Xqg4d(iN zYQMSOfvY#QrE4I%9m*gl#^0G;GhAZsOZ_XZ46YL(Q(x+Ci+N_(7IXa~y+Rqz>$=EX z*^FEd?%HXtesf*gb%VJkGSit%>hi89n(H!iHM*W3k$viVTvMs%b=_=XPsEk#y4hUl zIVj6-dL^)TqCJ5T(2=I{RV8t zqLQjMb%v!Ii-uyA=we(`=vhC`TvwXw_~6=YuBqU9nz>FhS6}KDT$$7bA?&X$?9tIQ zIrOFe*212JOBue$Fnf9QC=2_bg}oY=@cbtWyCZr^td{jf!unEg#q}ES{5Gx>uBThN zpIf@OM$a*LwHah-}n9Z(;s){T5I~u z-g|aAd;3z`*Q%G;7wJni+W=aET#A8&*reV<`$9ww_H9ycbIc~7NU=@rSt49P@RKc?3l5dk-~>!3wLM1EwjR+;20=dL>OFvj@!oC|!cU4!WKbihieVD@Bg7)J&jj1FPu6sGugNbfxyIViS z)Y{V14z;K^$OT_I(^w{tp2{(^IHpHWcQO!jq4hn(F_(i*Nk5&#w1p{9FJd~xF@yC| zY=_wXn8Nfjrk_E9B0{g^n9_68^`f?h0_k9IZ^V7V(`Kf%r{FM3tx%=n$ zwf9m=dN;qqA|-tg>jc&;)@NB?V10%49oCOoKZn*7C;U2zNsjQ<|(^==U zz6X`!bRg+Bte07D1)hY(9YpqE)&fCaBU~`(8)!UR$^>0NxH@YC)|RZDgF3;U!r`7A zP7AsW%TU&_tP|P(bP$eA;+Y^SYaZvhgmoqBX4WrQ&jkI7IKOiEHmeAxx;d;K))3YL ztTC*Gf`3DtBEcuo4+CIHPJe`TJnJ;pIjpa+z6XsLn}VtSlhQW0N^NJ(T+AS=L2t zF@3uN@qI)tEIwiv>t1Mb`X!F}6Er#fCbX*fGjs&%5E(|{;$al76h>_v7B(5-N5iOG z6aF+T8f7A=gTHogm$VqX-^ zvBObx;5Y-X6j#{(2WxON#VpKPfwdM?isq~xqun}Q^opib!&oP=J%ht9Mh76zrO{OL z70{IQGw`OQUuM0=`Wx##Rvl9qXO0bGT53l$iD`?p?PIRO(kF&mH!z0sp;_l(6q4bc z$d->{s86=VxRL5$4ArD#>;=T>9yj-u6PRh!+bBQau+J zq*}dOkmmV^u*8c`IGoGgz3e^2IUHv_$9jeJI_q6lrx0z$0fnfnaA>?JScvkEV@qk) z@~o8$QHj+HeU9F%S%kt(SvwV>v^|PYPo{BrIETlvKFONJF<&cE5XXqOio`)zz><#Xk<`wh9RW!=KMi}fJuG1fDz7g&E{y~QeuQ(8A` zFl!OkvaD5E8?z>}_GcZ%I)(L_;*(`cdJZ%>eR1(@SyiklPTS^$lGNTON>ZPgo;Q7- zUXtedjFJ@RC*DUrTax)j`+S5ZBsv&%0~DOt8Z!Ag2GBa;*z3J>CrAnlr25p6>mp2t2EW~h0;`i zn$M1S2Np-H=2V+mKSx@}&ViT9P|UaRsDxT`X1IptY=uSu-;^K zm8Uo%tVLNXvo?TA@gnOh)DPRse}!J!TmGagCH)t8Q_}Cko09ISKw5w` zjqgc+tVf^)#5b%zSLlTBJyxHJ6b@r8 z1kKymm9BUdwXMvW2u)6JR*~9xj`jPBbhN#~`ZHVZvbri!+rukS%p$C%S1C>t)?{tM+L3ht>jc*6tP5D*V%^Mofb}BlZ&0j8s#1G>s*wh=MnLoSDg~=iJxj7y zVXed3gtc8Y8b>pG%~-j+H`2Q%A{soVyjatin5kqEyr4w zwI;Nxs9T+C)r6JC1$kDdzI~LnALnNFeor7i<^$^t*4eDjvo5Mm`@N+IC#S!~metj} z$O2+r_31tZL@xBf71Z(SufX!~I;v2@2dKYUiP73XiuY?Y$E$BXsnHs`s|M|jOY%CZ zD(lf29bo^aMi=O>HK?xwYm$~_ZCtYl?5%3{fp)7o06Mbf5a`63lV#ra^?l6_zA5QH zv0jHJrx&V4EnQWM%KD@h<#wRfa^I@rT&<4YR7DeqAXRbJQqa8IDkXjZdkxkGtfd55 zk`T^|(Nm8)|sr&vA)duChH2;)zG}0HzeLeo}aSrWj)M# zp7jdrJyut3iW$fn$y$W99BWk`(FS$DA>V*Q@=Csv<2lq!Zb zj{&Fi-|^|IV4>B+3!So^XLWF5{rmURMaI%^hdHtPb`msnqAUBFnMl|aZ8tq2dtUA(5eui+9Mx@DXr!yL?`WlfAZ}b6X@|Z@njZADr zbM5=sZ-*oXmzP#q&baAm#{`Op>PaTiq%bM ztJ&Iw);V7^xeUw6CY0ypCRE$o(7ZmZ)ATY@C9(Ek9mqPCHG_37REi@_l}CybO{wOi zn?)l$u^FESu`Yt<)$lENQ_|P7_Gn5mXK|eP<`kb|O3|nV)ubhBH`ehjdU^9-*MfRx zOA8!R?773|Ee0dc6VN=%#TJjia)VX2q_9704C}&xN08f+mbCwQyX72&SGJ@c*w~WF z-Pw|Q`#*@8ms@bsCgczSO-?VEL`R~EN!yU>ZW~Hv&N|&~saBz^McUE|+?=78YfHJ+ zZ+jPCE2cVQrPP*EnY~t*wsbDpo8ydYt8fo7qpdGAr)>cA4UYL?TdLL8wv_hswxO^e zW&4G;eY|^#p6#mo(>YXC|GYYHj;skwT07EVt!g5bX=zk@YHxgdvXpE81hi&*s(GXK zRL^AA{;Z}&K^>^v*bY?Z9v!F^eLGNnOdHKU+=Qoepd6;L&Sss*`ep~pKc?d*lv|@C z^^CE!=t%Y&9cg3-v6>Zl6Q1XheEy!lRz;Gj4yBVRhswz^fUXA6d1!-VYLQ7hoVN(G z)tEEWQ^}LD@~8cLRdF$yu61Q^K@Tt42fIJ8v%$DnmsNA#bBa60R}{*>D?*3JEkgdd2*1w*kwH1(rfl5iAOMX$Y=`mhsY5e9N>2UO*v4rhBV@7S4g%TRP~U4eG|U z%l$2U5n`aFt4w1o-C-JM$sLe`m>HJBnVz#07cd{bmkf!D0V%li|GuRL0WX0zS!#-y zQDV2Hb^%NA(xO9_ItRQf3W~FqdIzi$g+w7dFD`I5EDd=U74<9)4OkCa#*`t(u+PDp zjOfeBlbQNin!!{84}_ENd8TQW7BVfjv@~EU^4wu*C46y$KIcv8HUxYO8e?g5z*Z42 zp0KnVzIZX+(tl91Vq%-6)5xWm2%yKZkjpiu>v+_k$Q?+&V>JzhGacsV9x_BRrlI%| z2F0w-)UURoCQSP*B{QYgF}^gWJ(eB|%tZ;M>yj@=JRi766c^Pky}{Jb(rTtQmbNl= zx3nj4AJPq`#~lRC!Krw&^)Uw!Yt7|t160EqWMxy zl(R%LtC~o(M02o)SZs;rV4}dA@HkJJb+ttTlbL6=#T-jtqP4Zf2aPFaru$g%deCO3 z9pX}OHmFJylM8JRbwqt8Ge7HyDVAt{))D(G(fq6<<}{^r8RBP@P)B@YiRLE;wwdvX zkQ7l@q*{s$iI;W7SxYe?xuU+fVyOhEfvDZwq^pRS4Mj6ciO8j~c&x4QwP2cKsdq?e z*;oX$H@=~uW}=IwQJ|J$b+Yk|N4nPHEIk~FT0g}!2lqvYo@HvrKPt=+%R(y2)?x$h zl8|pTd~HR&UWPtr8rGXAN1P7X1K%V|--aZ}wxWAKa* zLUX*oVBF>UDl{b@oeIr;fKnxX%Vg5IPK7ST*P^%gBfQ|DTzZSon9P2+w>V~elJe{= z&Re29dy7i_kxX2Wr$SR@AJNuJOGRH%Dvf+|g*$AtOcV8(ObG+=#0L2?-7#VF#X!-) z__%~YqPrz3VUSqnrBpds?C{c3ybEZ`5YB~z11$obqJ27m694$Vu)Hp0l zj20hT>Kc{}%JrtpkYmL6`O=LOSM#MCCvN6TH;#V@NPRXxEK80THAhliGTrZn<%sd3 zfu)a_S{Opj<|1Z__5FsrOcZ^*z9FC|tdDB_xR_?CQurd!Y)jOJ$HiPr)P~2YXrXzp z_>P=xX_ssnzEV!{(y;Kg@+mKk58o=MTB1ICM^5wlT88hGGrTk`e4m`@B}zB@fppnk zU(4{L@;NUJ3;$Zq@e-w*_dvS&ULTeBqL-+=MP8zGuRM_MRj;pQ_$9f-OT)si$=AI^ z>E5 z?Q*q>sH8qM0O|(H_0sT&>S~ARH<}D)d)O)H72vdT92=3Sc8SfFrh|5i5%kz0e2XLM zt36`MSfX8GS;PdnS4?Nh6l;*@UUAFPX3%FMm7jgQAgR31#W*IkJt9Ty6G_-W@=D() zQkiyf%>81n*Owu`5MO$!jXEd-#^Sc;9D5BkMY zDfmu`-z`;x@1!U+f%9}Xi0rFQi4vAtM-BwFv6KSeY0=qI8hoe4WJ8z*8S-nfgvr$9 zoH%P^QeD0g7cEg;z7c*CO?gz8Z$+3Ts>`<`foXyGAo4MFUNrO46Y7H4Y-w}k40T!5 znnbxQ5St^PS3iojUV2Sk7mxEMZ`S&EMF!I})H6lg71>M+#AlJK6^M5S3&hdLb?Tlt z@&x5c>-iM%hd66UoR8eB{t#~7RZJJZM5f9=#G96Wk9-$TpT<7P=>#2fgsjCxGmEGp z6P2EdNAo%|U66hSw&4k)ah8e{*sC15+K{JWfh^&XA6jZ!U_EHPr4*)(mWFf8&4%P9 ztV29<2a_q!BM)02mFFjKS)%d+Wi{U2UEuPaR6-B-!mdZz+0By5WJt|d(%j-5> zU8IYUaZgiU?-DJe&Zr2PV5u9ZfJ|aCJs&MQdg+#mmUC=OT2&U5n*@yyL$hsh3L1LcHV8bbl0mLY0#x42j)L{h7>YmXjk5d8h{~%JG({2P?`aEm03v zlp|D8 zuM+#3@!`>&Kh%-QmgxMUj_hKI&L8T?ZkFi$p^hA6iOwJD$g!5_{GpC~$`GHm)|Im@ z(b+^@`JyE{o2W0}uta0qK)!E@&KMfYO_r+1)YVPoZcB9j&{AHpL^GtN?4QZ~f;ll& zw3d&0DOR?T=}fx>#cU@JGi8X(m@GU)cy<=0%Mdx}iH@=mF9vADrh+PasjE(wjl9%H zcb1!(cFDy^mm+8LvcZf>ikxeSMkPfqw)6(d>n7i|bUJ2&>?YS(x*U@R-+rd);%3ZJ z(OsUk7@H#c$!knz{QAjXEz$V(lfPM_@#`n`bCk<2 zH;rFE8DfdXub(VziN>#=ENh6*|N6@smT1HV$i|lF{BNLaXNh`upzL9(Mr>U@L=Lh< z<2OQ%u|#KXW8@r5G@4`NEv5|75G@)bl@nx! zA@N0QE}m3<)zZ<}_2O~4oN1S!TppJfEm7%HWCAbkb_p8IDe^p1hB%A5Op#-As4iv; zpCTtSnJs*ZoX%vn@TX+9m(s*ja=w>_h^OUihWM&chJ42o&5#Va+8cAKn2OusrtQ?b z(_|G()VtHO95q~>L4`hj# zDbEGsy+Swihq5zMrr2I6Tdb3h8gd^jlqJ^7XDpqEZ@qlm#=HsoNPcR4{)H#V4f3?5 z*urUIgS>62EPNYf#9}Hh(_It3jk1a%(X{X%`eQlF`Z^TO5?kbSOT!CigO*sDQFy)B zDmPi0gFLs&uPnX7zMn0<%f5hDOnD!%uZJbtR<_D1hQzMIDPo(PZs`!yHcMww&u#K9 z6Rr;y_Hnk$5wCHc;$Gn(Cs&?j!qvheLC#KDhEKFE@DY8tOk~;t$`-q27Sk?C^K*}! zXMB83Zjao-lp~^w6ma&)kT!rh2KC^Mzc-L|4Uf#R2KOMKLqQ z%S9VG2W4BP1>)_ZEu88 z^h$9l;;39>QJunJ&n~aXp>ml7D!H z9y}4(2Nd@nmA61#0-cb}n0ASKaf6(ba+D<}e!Vy)pJ2)qA@ReVQ*yB(cj5Rk&T09k zCA#KuTCTBFK0ZyHmRl{+_VBgbXDJ~*7j(iBZ4YPU_m&#McShc@L|e{Tsg_ecGu>^F z=UEwIiME_`vaqG@@ST(84T-_=@$ws4*V4%NJMz42V`EN;@2f7z?v|#;4+IUi^j!P| z`Mn%v>BaaQ@x6S)(vtZ3plnO;#%GC(@{}R5F@B6X5ZPnDPD zb4&}w)%Z;32f5hNpYhK+KgzbNI330>MO>9z4e^z)t8%v`>d&k4YeQm7@d@&pykLF1 zimw;fiM6g`+d`&)bqc{5KGkazsML%)b?Lxyd`S;ud<;f z>cQ(W$rAP8b@`5^W2nmw`M#y^if4g7vUI!nW_3euwd7OcUHJA`3NJB1{w5DtiYt*O zev{u@stDgrdDT)a_-;y{)us)N;kzY+EVYC0mMm$BX3uR|#S+b)+j5E}nmxbE>6U2r z{4N(;>QQ37xFg@RG`K`AXr-mc;JYi=SxSfRuH3?8wy}G1kMW6TOQgzsGT{R=C(g#= ztX$@NNVH4PR`sV`Vu`l6Kjr?l;5d-0O|+a)~IHpGx#nF;}p9%}W(r5o({8YPzD;bxSu(6mu0)NgtV9TqPU2;?+t^ z;h>Ug15=JD2`a1hS*lwy$yHHZv(yGuNj2I)x!}rq$@Z?wYJ{c!CA+w)sI`Xpj%HPL zhRLjHtE$Uhij~!r&qm6{oLeNQa7(nOO;GVnX60W)RkB2@yc(*iC0gaxPzjc3l~+SG zwnVGE8mhe|TIJPHJq__HucjJeiO$?=s>dwRDlbtzZHZQSwbg7(w92ce7FwcJY<;!O z60KtEtGb)0Mdt2fBbCIIDV{IY$JIzB8{*?;W7Ws{=(yQfJz{-vF*%?q))x>nAGFQ- zUMrO)ny6gs`><3lXs0E*-qTd=v9zJoAXigWZwvRX*jZ{Se508%#L-eIqM0HO>gj4x zda~<2U5cCRYM#%R;cB5?<#ZP$#cZkGwnQHiMC0CGJ!y%?y}g=k zh|l;ssFy6!NGGdhmS{9PsdbiUG&`xCmguamtNIU9CZ9=lRTr&~R!?1(-!{`CS`&3u zQHFR;)K!&W%5ZloodsWl^`(`bYhNXZqGYIHeNoW%Ir1ejW7FwYoyv|DZT7c@u;fsneojkyIzb{bu2AlYG&z;va8@bW{I}3 z@#=;lK8BB1fuD0OmZA-bRb@X$%ypJNDw``NsAHD4!8cLeHss!e^6-1keVmK?1XGM5 z@nhK(_?lRsD3=B5VtwJ|R)LcCn>J9*o=}r46)v|FROgHPHG4`m^HQ#ON_F(oUf0v= zBSU=6I73}F>6 zIcWN2R{2ypTb=RJQjx6&9=hKz&#MFfAu@L+pI0NizT2+n)mcNLVyy6)qxu~-c~bAb zpw3!qQ!z`-SJy1fD!&vo{fLQ4qq0!>d}S!5B2l;@?%jnd-V*ihLRHpM|B6073sqH1 zqbh#sTBzz7;;TQ4)ZwEh&nJ-QODgvm5w7|%U9pr?aXoxpjvL>r?4wWkP|Wu#2KcN;+fc2x$Ro24jJOv^SW}*vrjx% zIaj={c3673a*B9EE&0y)-mTog=M8n&(#N28)TiGY-_FWeV!1kOX{C_G`i`R3pQ;s>zO523KUGQBO}ZbE%MLZ$ko!)R zEU{B9w7!Zs8tzmbZG6ikndsRm-Eft@sOO|N=vS0n?rKREv6?xC3 z+fnUB*FjaqORMm!X}>?%=cc{X5fx==AIdwTDq5ob*%8&s673_8sKJ(KuXsd_vP9eT z5%rX%^VKNkXgmv;w;kb^*i2@&LXsCD%@K3}ONcz%+oCsQ-$ zelB0Bc@I!C{JI1&F)FF@E7gT5LkzBxDvzopJU2g&oLE;=Yfgn4)}4^#S+~C zKdG`UT@0_TPOHt9zNubaeXXuoaz!llIim`DI2ZRX)!*?sr%GD#O;`b{WQb?TH>&jm zG|)?%e7;dLY`TUCS>jvutfig_*`NiM=&r(f^{OSht8iYuV`+TCr#|1QwU%Zk>;`>m zX;H#{p9|_UOYbEd0)1m?Q^E;cTUK$^s>5CVi^MAWscWP$) z7RpC+eG7ZZQ!CpSFVnU$J+t{KhUG*Mh%^HPc^p>Ycr zaWmZ|YE6(OwA)h6T50f=u#{9QOO(_VEcL0C4N7FXAnCb_QaZ~LJ(E#dA7fe|#??wx zWi%cVMhWH^S5^;XS|HMEE%7a@heepupR2W1l-J`dy;|#S-|~6~(*pOox}Dq=^yijt z)J*{$G9*0pdbum=YhFroSJn=`w?k+8G4+PJtLTbe8ttyGds?bcZ=$<~p5Ub?-8JQFxyRKrq_`Z=PRu5W30{rR94mY#sGxo&SM6TarUo24A&*+P%Bv;ujy(3zHY z!`D*JvvjX$=x6qRDxc@gIU)Y*MeHGL})paf9qJ*}(v!$=#Yo|wA`Wn7=`fW=W z8oc9fuUA>R+h8T=Gp1?ou!irrJLs>iuWG{+s)N30sbRxZ*+C~1Hg##&aJ}fL=U7T@ zm<#%bX`1_yhMQHg{=w1=#7x$|S(?Y>6ro(EiDeD5;agFZC_`*)xYpfCH;gkS>~AI_uGv=&EfOy~WaZ4T%mL64#i{Gns37U35Y`Z0p0EkMjo?k+mX zQedOis;geXL|YEd*!4j#opz__dtMr-y6Gy#D9;NX+Shg0iI!+z*IjpH%5+y~a^BrT zcej+-k`pDA0rm1p_-ezKQo@4bMn~riBtK&+Wwo@+S z^|&%b3&eL#U7qoJIa8+lm!^Hy1pT2U-(~|rUt22Ftgo7=FIXxM-$Wf+mU78-*MV=6 zjjyUX9N z^^-c0Dbu|dr9Y(`S^5U0Kc!PGQO%y#11(X_p4RD>?!cF>vn&NQ9|(HW5Z5fjJDP2q z7x!f7L-~9&^f@o3${AWz;GPhjo1ehDlge4@*E~gJ>ehzvEC$; z0hLV6RyS|wc}{<6X(MVjN1w8^yLm3iscd2%YW}Xs(P3Unl`rUOmQEt(T;0*q1<*V_ z$kNs3^Tm9fZs|7avOr(ABwFN%7j;AxQ-Y_(dQiHhP^KN0=*s1bI)?F_k>wU{7Z z)m<&ob8@fh-j?V&xmWdIZ@ST**YtSntI%?yXNi8&(sS`of@WB%({dW-4shNC*^=VppaTzGx0@I zw(kbr#nREFA3YoODKFjde5~grnwS@o?szuo#aPn z+p3h`UY*#?#2nVDqTgqFwU=u8?biX#^L%OIOI^oHcjN&*!AlMN{-f7=sfFKR?QW5m zF4^y>9_Xb+-;;W+rID!1DSge-?dG^9p!>Bn>25bq^!-|IV#2)%^w}Bxou!$rdi$N# zo+OHyA?Cw(P8YMZq*a>VH@d#16|L~ZweD(ZL#rWv=k;hyJJI&seaa`bW<_z1Gs| z=4<@^(APVen4h#><0qUqI~&^DdXt}W7Irao96py*uB)MMTTd0fPJ1um_oB`uOP5;{ z9Y`@T?=s!(X~?$?`9gaUos*GFg_tr#l{VS%Wiy#4fjrJa>uc0zx1XQ$t)+HtJ_p^f z)V>IW&o97 zR-?t7crP{fFXnXjQY-%w&bwZ^BTGALz0|_5tm7J(mrE!A3Qip_rTSNL26}0*e-&r3 zmlA!eId2iNN*~{A)V(4Dk`Drqjtwsj`;S-=^Et zK1(Dz!z|HV#6;(DOJB4$j%{6MkoD31;=0aQOLQ-}t~1^e-94`BJZ_2Z9@lj;Ez#ZMx=xlMe#W|qY*}owL?QtFExWW zM8EUyIy2qk-^1&pJbQYH z^1M%!=Y66)dwFA0o~ceFQ)>^^Gu27*wrD44w3kME`Z!aVb_pu4uXENCmDksqKHQ8L zmDkrfY>CS2=eQp+J}R%j6UT&SaXNnK-{0B6WcFtRoc&(f;y=Lo%8wggEm7$Monj;Imp;(xVu?y0?%7(du`k)0xRUWira?XNk6eQO-z9H0MV- zlP%GfGs>B1iMFv(&OA%Bjg4|%w?tdjqt5$=`0n_l&Sp!r-9GAkZi%+(G0t&IwDpg5 zE?J_jf4pR&vicg)H6dIKpqXv&@oz@@@ZYCu|(Y#Ar?x&p8de6f2*19x>#mJ3l$j zW0vT=D#w{(sabNCc)^)xNNgxI&GUkDb|U4OA^ek5;9ES&P_N`{P?^U~&FFcXxlY%~ zM7!Md#LHYK%@U3DTxYQ%LHp~u&Tgg*F)Dc#=#ZtUpasrZOAA1YoYX0tCm$^qJKLBt z#Ov_A=B$3o_-Hg==lx6Gxo95IN@taL)B5P%OI`hrm&S+t1gvn5aV}zqAIRF|n@y;ET-=Lw3HA34t(a??H2jm~02g3fFZ% z=Pc249-Ew>Y&ts2+T{FZiO#Y%Ie#)`h=5MGAMTW$M&)IQ7|pvBl}agtO$* ziN0H%B{R8Z{G8P`XVPqw?n0aScvJfcrW{eCQ&_-uCpz2s5;`UN<~rS(%r9$pIML4< zU(-%Y#cpRDllf)MXBZ>AS*Z(s$>Uq7#(RbS%HrS+iDW!Yme2BeX|j-A<9)~X<3DUSxpm;Q*kF+JBdlpirSP_8%3&^ziE4=lL zEFKOU@BJ{|6AwEcX695etp9(i{Jjy!eNq~V?bI8_d$RIbnsC_kZD28qc|T0=|E2yn zam+}Wa9hqTf7pz8el?{};Fuq>9%0QN$AoQ6o--82*3^UMd=sb?#*)gGf%z==<2Zu6 zE@8YT&xdESu{@mr!|}~t#cW6S!cex`7jOEb z7X90pZsF-k@hh+NetCwF~V9b`%8->K7`#Rwz2pBE>-^iyn%d_xXZca z51YPHy{INna7zOae(;F!@P27a3yM>TQ_-H>5s3(6*8Nwz9&E*bd;izbtvzz1_kB}Y z4f2KG;Br@RiKdPDk6i!v$2f=gPAuhSC zKL&IA&-l#W!loHR1bXjkk?+ z%rHJ$nSJa!>{X;lV!Ju|n6!VVroGfsdfPs=;^FpE{>mN`Y0s9oU9a$#uIwKE?@IZ9 zv76SJa!tGbZj4Ml%{tud2OhRiFDVhBq||Fl-L?dNTe)bVYE#9q;mbiRMyXDl>u)Tk_XxG}?&cKA(>~&h4eJ z5+%=SxRdP6!{D4e%l-?!lV5CiVVG2#2AD6yKorZ*_8#a<{@LCBNdD@~fep8p&^ z%(?w@oWJw_z-bE&ykDZJgQ;yPwpYvN{kwdO{ojnmKd*01Kj+^PXXY#YVXrCI*z<4i z|6I?1AD>Fk8)d3h-WfXOAcd*hef_JL>$v_~SShT;UT+xRjpKZb*5>0yel=-NaD21Z zr8X))$IshR%q%*`aZIbtb(PC($v>C!pB-F>SK0G|`{BR3>Se|>e}9^}VM;OEvWY`i ziSy#|-`dj6Wn z4yMv6H@tcOFT*DP2fb7)yxE_R_(qF!+KNyuYC|2-8k#ryPX|#cru6*bL7d9isV!Lh zajN|D_OFjDe>HEXa&FT(2Qwe;x7Uny-uN2tKaajiOV=2c$mBeq5bef2C)RFSMWeU-v%Vpn#`mn{c@g&#e@8;)s z+^auBwYbMI^IL+3&`dUCn!i4O7dEq^6jGVvg1JJNcbzc*>bC;oNWR{ix9&AFfwubp zWqG)z4_oqYL1ryYeV8|M{@e0b*M$DN5mQDf~^qznXYQ zel7f~BhHHsqMt}XxI5m@nJPxe-uTxS|N0}|P`n|3DE^MXTkRjkyXD8>4P)cQJ~>ew zlTRaEE4=YOMTE+We%T@hnj+#kTo#%ps z&=fpjNR}9WmzD?N6tR@;@5&Fm?hn|`;ZWFn3R2XEB+0(HcU?nT#^G)ehauHhd|fJ&5>0Cf3{wF=bDG#t`;Nc36a}um&)Wr zZkZ#=qV_+#9MBY2HEZ3o`>eIcxs;Y)S*RZ8F;*1MwrQ9g7mD=7t9pTTr&j`B2 zUJt(!dW{&?YHkqak9T3que&dV_d@r#p+9!d#d}YJd#ngrBjS6kgT9=!UaS%Hoc7~_ zp2n-K=snJl3wrvlzpB(@wc03J_ZSZC4E-6Uq=}!oH-@Pvdh~_;*&Y{yHi{*z>!D+8 zyXct~>H+FWdZJ~ci0oM+c%vxXvuyBovA##OV5)fwXw{xGf@*X9ALq0gtb1W8Eo%#U zul#7&T-xLA_t@rp{Y4& z3)QWa>YiFNYa%Bqx%%ZR|>-W zOhBER^ePrgHTMr&Bl|TE4{N3F#Z^}xeqU89)wWM{6|ejExrjW!?!Lm0;(vhLCiE#3 zwo%ON(-*nD*rz_meQlo-!8F!$(I;E`&>Z-@&wBLCVb-r%FR)%^{hbvf7#5G;242Jm zwq1RDI_Q(W{g88H-wQm4bGdKlv%U~U^L9g6jG(8iVgx-iMKc7yxwm&50+XA!)__n}Cac0180UO250bN|%k@Fo`oPkc%MiDZwFGjo;YZ5E{ zs%n@@k0Jv;(;{x-hr->hX&4%8pH9Wq~B-s z*M$cij-qy*fOb#47WKGJ8`LfEaXl33;VqH&A-Q-z_pnx#qt}R;gK9vt2i3(#zUbFi zYsBI~sR#!R9^`mr_Mj!vwFSM?nnpQ=_j}m-xWpJiPsm+Tdj~I%xuiBnZitb{e`^fY zIaN|Wd>^w&(%b1`6cnn&P<1`YJ5N^h4lf;t<<9!O!EiMWl=oR4)y~d?n z=X`F75LoVtNa+y^Wg2ve90E%PMfNJ{SLGIM6_wIaMZ(gBEmJTyZjr92p3~WzrKpD4 zstD|JIL>)RZMn#Cu5g@dit2e?O-Gzt9Otf@g|N`iK^;98>edUP0h(fl=vNSq(62+I z^*hi)dIfZ?F6p?%22K62S(iijqFw^MqN((2tk+p@vEJ2h!7H5ippHYm>UO9_0c;6z zsPqWdXs3vFi9*i%j!VQjYoH~Z520n8bOq2rtjjvtx**?cbqdCt- z{kG8cF>+h%+6rCb+Tl`Sv+I47wTQm2`=0GD~+B%x~QokknQm?l4r8(cxcQkVA;!Cq-8Rxcwb6d^1t>xS{aBiD9 zw_ErC9!A7X<&Jh!x#Qea?j-lizStJnK9B7S*}jA=Z@Q`6Wo{~Wg_}xT?fwYyH?Vgz z$KU4O4$BVrF6bWj=g@ub1JDERBhbU{6VPMsGtg7+^U$;IOVIP~pP(1rze2CLZ$Ynf zZnxaj>bqR7@KEnL_*ExH!9&|rfQPob5D)cXgon1TXpeGZi}UzG<2*DLB|HHLm+{bu zRPfN8tl|lUC4n{3Lwl-vtc}>x%u@i~BoB>RTh@-Ag0OVq(z~;!dg5T|$2!nc65*k& zBRtgqqgls!%E3N~b&97l!s)EjJqZYBv1YSn4(mKmZP*vGF7`A)cnRy9o~8&dV_o4% zLU=XnT2DKKH?Z#T&^Ye#&^Ye%&^R9O(EK^6QpXR^@4sYi8JJ`F2 zE&E`pgyYc9v6aLVBBEd=ytAMlbb$C0mT-{OEf>Uz)szoytTe9M~aPhlNc(0652(?ALr#|v^3#HGTs)!>-8 zsIL07df(VXHmYDKyf z+CAbNbYevR*0a@;i0#mw5wgu}bt$4TG$b+uS}$@tv`?gLJ6lbUYz%!TG6VWWb@Xx@Qpb|l4gA#%ggBk@T1$78Y3F;j*C1`fg_Mk62XE7g{-VX6Of@zG20}%7hIL8yPk(Y;xGsVVPmG!(It{BW!ipmaqe1hr>>W zoeR4b_FLGUFu(BN@B-mw!mEb23-22~B>c(ntnek_%feTOZwTKNelGk%`1SDL!y_W% zB5Fr;iuk&~r2@Yc2#hKmRW7PlRHvv%q9#R6jmnC8KI)aIx1zR2?Tq>&>U`91Q4!IN zqPs+=MURf25}gq}D|%k^ThZ@DuZ!Lhy+8U$^vUSU(P1$$F^ytUV*1296Z2xst1)lI ztcm$7=2*;+F~7vfSl`&N*qGSjvDISh$2N;?9h-pO6{32feRyIH&*0*Jj|jrJ1mk)^ z2*xQ?1mcU4L0Gi~V^to4s|STdVf;_m4vORd(pa~Z$903sqAX@d`A!`g(kHEZYKd$9Lp z{Wo#ehjvG9--c4Ehc!LyNqA?3QCa!JN5Y9Dj>*mBWAZe)#T28Sk1s|!mnuf1R=(K%@oHF#a?YRD#4)LwvA10* zir>3bPnQsbOHn?LvW{oXU)GZxKa=&}%s|t+kug-Onx(0ff1m0<9RJrcRR4QrX!KoW zDI8gr!e*?CmVEisx3 zt5MjbGP#+2OrHMLDSoAd^+=mhlVX~=w6Nv~Um@PEIR@Iaf-d}4`56eVK z6`r^Xaq8Baj^oi+jmUDE^?TMEjc7!IeW@&;#?+Q@*4V~m8D5*TYGX=Ok1gYQTw1cF zE9)rMS)9tn+oqXIW)9@AeF#&)S32Zf{oDljp6~oV><9 zmc5;WDd(qKkj`dZ%=&2ys+HMSoNhTEIm8!x8Tx(8rO+Q+Qv6#jsSlkbsSx1(?*Yq55eXI_s{4prMx4z=19@Xu?t8S7^4$lHNanQ=Gej%`n+KhZuN@u#(? z+_KwK4vSfrvzF^XC7O9&y94#ipbqm9-|TbDp5Gh=^6&r6QNUR8$1$lEah^dPHy|IQ zV>_Ne*o?RteKYR)>+|roY4XWmt|`m(+wx?px!Dp;9NCH5Xto;ahY<0kR9I|HfhruW zHIC)MP&^xgm9oN7+!q>#W4pp?72lD@mzM((j$o~exDvCFD;yau12tS2Yfx;@UBrKU&A1JK!NVBj) zP&oFNhy59-!iugUG#hINC7#6{1|^;s)uH%xJM;yt93<8UwGp1n`We;`crJ`}KWeJ* zUBmjYe2JPW@dZ?hgQzL)6|)}3N<@kyP&|!=wFZ6%09E2L)*MRwfHjK3HKR7rA91xv ziC?hx!1F938G0S77bR|puF#vJ8`9o_Dsfx%fZoBX1kZnAO(MlTDDEfYo`@2DvOm;c z4uA&8LC`=s1aYF}FodI63*x(}N)(nOp+)4Q(4ttgD6C2zL(F2he}X4BSrf2^!8h5V zO4P(!2J2|7WR$4IS|6(!j1<;07%7O|P&V?lls_+e@`3TQueHPyX#YjQ%1$Maz;pbU%h# zjO1(3d2%UqzI+2Q7s$5|enY+keM`Oz{Xi~J_Q($r-p#sK zu7l+>D4tZ6A0fOCs>FU=ftKP6s1jewO$Z-=Dtxo$6NC>#l{g}|B79VCNBAq&V=@=v zGjb>FXQ4`bBX=YGE$esquBH;_p%PyN`5fU3tQX~eST3>tAisqDGV2w25aA!?A?Q!? z2;y9YDtx8mD8fIp{wj~d@(Wbrs~9H{zRvoaJPpfDsKS>m&LDi7^^QCT%kQjr<+rfk zV~tYZ!CrthT78djjJgDkRX;!r;!BiL6joOeF2q_I_idCYtA2%+S2v(_)J?>x3sv~4 z!EI=LbqCr2-=D*+Ew{OQ}7)}h4<74ODVdu zrm0X^#^5W83U5)5gpN~DP+UcYKB)>qpHhXP8LB9Bs)~osSH+8t;Lp6l` zIuw1b8YBE0>n+t3mfNg%RCCyWXT7Uh!hR2`#2=~^!hb@Qh}3NmE&xUU>vjmoLec-a z1Hy$^i{lG>N)&@iypgms!X;R%>8=P@*WF-GV6CZpz)}N>En4?NxE5<|-5ZuVto3wX z*z2;^*ZpB{0L6Ie0SGsOVjI_kpiT4;Seol$2sdMGp&voGr5*`wtsjN9(PN-(^<#+H zj7_wsd9frk{qrI~2cE&>7I4dKxUfpbGCF zoPls}s1kkjOlV&{3))Z5h7Qor!aER({SUsIhW(Gufn~Iwi}0hYWAuDj#zK{NOuvZm zIH(fi^&*5PK$V!NUq*Nm>ty{3ERVBJ)2|^sQ!j-#3yR|lzIrC{hPXEnepbH)&C&0` z@&Xk5D}471#~0QG_|6&TB)p^V^j_$f`g7<3y&rl) ze~I`fSx@PMu$T}Sa^taHP`a7h( z1;z18e~<9*P#nedC4}!nmAI#WK=@DnBf@{Mwsx)}+{XDC+Sd6M+RnKFZSUMf%nne6 ztN*tVPG;@w+<~PNYd7Z}!rk!|9Ly6(D$E2&LkBu8=wQbeI>hlnhdTaB;(ZT+2oHl| zWSwAyC$c{7gd#lI35P!6L_()HQP3xy80d7TAassX82YkP6uQ)jM-Hz;aoll=Bm5@o z+fGSX-eO(ml!pCXC`QdGi|}&R)lPX>-e+CoR7Cg#r!w?I+*ws(ty3Mk&Z&X;>!C_~ zyxD-V;8V#T|0D6dS42N9Ftp@r6XicLV>~72q#-RY5k zu8p0oFtthLYyY@PF6)P#+9Xs(uE;L`kgHU-Qr;@7wp3=G=Y7w)=icrHW+>TCxoU>Q zz32PmJ@5B9_cYS~*+>@QAIbAyjN}mhmm_(k|1qAs=Fg;Xp6%?vJo~>+b{_k~3($;* z?|sRbi^E^X`O{0o_jZlBJbZNDn3>@ZzYU#uIQ739GdDbg=au1GcwQYo!t=%9@8J2; z@E`tTXw1Wp{}ThA^6h_Z%qzpGkD%QSAL04x@K5pl((s4F3G>?UkMR8R@K5o4eR$*u zswI3auzWBsW6qy#;R)q9{0Hd(-MTmJE0UIiUU|`c5!%@`oE5o-ow*#e!|Twdu0vbG z9WC(S{2Ay+b!dyD)me5>z=3328x7x%nXS*imtDPW!Z!6gE)?3Y!n$Qk>F=?yN+&}1+y6vF4r}@Q$ zu1_g-t6R78jbJZmcG2u^uywn0uy;}imt294$<`V{`^ucjwYTs@`_<-7kXz50(pI&Z zzk}wo?VZla4Yk^VxzTRzw1ZB^7hkBigRO3>edv?e-eR@hIA{kx5jD3^F)Y4ZZE`$p zk?D)|Mi5DoPFy_K+S_jg-JljN6gFgga)nuDKvLwYR z5EeDE?XBJVoxmVCf3Up`)MH=GZu^h{ZHJ-gXbO_QSQXkc(MYyd-6#5@f`fsulGsw% zezbrhD_H_q4)CGAe}F}6wT*-Hi3r=XWMKslZQBIe#zO4i^q5_|d~>JX48rI#=Dk;K znsPe;l7rUj%^f>NSHq?Pyt@2hVBxT7VdS!GYtqCdFd*ug-E;_baz`dtdGzkusYk=X`$`iJ+l;m z6;&Ja_3mP$3dW1N9&F34PFHzWVSzb{4cD8kyUj4_7QbBI3raz^3y?{k7dqwY4oG{U z+O3-P>fK1p@w1I){hnm&5Z20(G6f%YJ#irSu#!^cdT`iT58ge10H}FBUk)&Ex7dsn z_c2S6ftpqA9>`o7TMs%1jjp2vvhI!j8sH1j9B?X3F@62G^1A43$7nUc9XM3;vHfZr zgn))LpCOFR!HEQxZyxM%d_eY%=9XQzpr)h%3DEA=tBn}lLH>5@TZBNVbqzt6hhrXv_Kt%0K{Z z?Mf7LUk(~r3_CZ(qw`t^w_-U5Tx7?w8woLXve(&awHx(KqiAZ1o8N#UV6yxBjrx`> zxaXEy^0zkLl>Qpy@Mw(|Q&t(TwYqXkyWZIr`twsZr0GWbQSkz$M0x4Q>$)zfH zbO;ktye!{*qqTLLdVyK3-mC8&>}4DKyVYm{b>j%v&AM<9Z-8ujVIDlFw zL8-8Iu(uhsi`xZobOCC|HCh5MBJ=MEzv}F^THX1>ZqNaxL-p9xiXC%_W$YSVLO)$F zi%X@T4YaP`SGtVFz(QMgl|Uz8NZsIG*F=`GoLw(h=2wcj>y=VDTh5#H?Ak)*22-U5pH6qdoF@#xx`+LS!G21dFBc0pldP|{Ybw}aK{J`k&k z9teHl6@r2-5D+yD5Ywpan)wdex9AE!*s#)YzO#<3rJ%c!gVmzJLbH3b6b7N(uLoOq zp!&5aMax8RC{aNd+UjcSPEc+wwy~^|A8--}``Wbxi9KX{S{#Lp1FPL_)9so@;~I+H-|kj7O{2b7@0!gj`FXo~Xux{+%wD|- zoasoiUEGeST|fW>HrIxhA`5H7lq7-afQAE|KMgjG0#i1jLe-c;s2;#V5|Bj`;)Tdt zwsvo{gFAT5nJy6AwAae5rIu-z8L7{iZ_JtdrXC}$IH5U`!du7*Z^eI03?bE&^5xZR z>AK0St}nA*3IYHWf)|P2sR^K!@J~ zX^`i5S<^vE7N*rslW7=yP`hF_DKjA0l`zb^2h~~|ehhPeAEeWfr(kmvt((2>_F^08 zf49}XtvaCu7a&F@up%fAmATW+0{DCTUDK2qcESnQ45-;+icqG-))1AenCM;dEU73$ zuqIMGs8vjCW#OOM-8D63?y?|Ye4W5)gQ{eh`D`f~oXX~)~a<#Kctq=pI ze%&#!TMRU4Lw01L z7bofmk~Ik(J|JN0VOmt55{N!@@t9(>FT2=`7qDG15yc%`ZM1J3bOnh=4DFh2_9V`r zim8ReunAy1cd)V{y-JH=EF6|8D7f(kTGea$dm#_9DcVCMy#y7y`{qFl4BbH9sKrv~ z6q;L&1301364pY4oDL_3kwQbP7!frqb%;N3NoXxpWh({?7KVwBZcb4616q%QR;%Dm zR7!}%F3fd@66@1#SkmiF)_3J4Y|H!fD$PsCRc*Us_Ot;6w6>(MNX585U4Mv6UBu;0 zO^V#`5cshV&j_vFeJs{OyR}b0+d4GhkQdTu^h+ZOSSjdAs@j4Qyd5hg!bBNzxQrU* zv_$M3bUc3+pot0PITZ`4l@w1y<*-Syb08k11T-INsIhi?+U#xbl(yKt@0bheW0

M z%nmJmlih&i&lMN)m6iP3QhC|r*5AHSE;@^Y@;_?HiKn2VDwL^oA-dG1Tj_w*0;@BJ z5ol9wQF_7@h_ir-Pi2!@BII}W07lu3w-zclp_`vnKYK9p$jKSPwUqwF1UT#90{Tx^DrldGy%Z*GIZK;^WvqLv%= zCTw-cN$MT3fojG#1YNzhgt1vQo-`c^E`o#s4b{wK2tammVbGaThpgI%10C82bY(%X zkf^}<@}&?G0wq_HWN^bpET#(5MJ%x}-y3IWFHE&ANQD5$3>paGUf4!avnh^ShzaZ8 ztcZ#q^_Wybcrc_Ir^LKz4I^&KdaUt7p8Xbk#! ze*LD4sUKjKL-SWG6lDzvL^oR}u!Ey2xhvz8 z)Eab~O&BcO^?MAJ0A+;k2W`+S<_`Tr2v=yM30G=|62`qDIfO8fB=607ceUENZCVYO z0w5SrnAlp<&<(Qvc?umtU$fpl%Tg7SBFQ4og8gDcw#Af7XFFTKnFljQ z#oIvy;?+2`4+x8z;Y)`~e;y~mx1_Wk823H2tAl|CK~-o{ugAKBTUa9&oHX8NWZA-H zIbj(roI@Bp_gJSL~WZ2^|rVu zb*bq#YsGE5!kR{Dr6F=+AJVa?)KEu?=3yYYNF0vQXc=3}7t#cl5-ia+Bxs9DSae03 zAc9c&xoJhW>f3^-c2?G*BkdKimweB;d$biz(i(!=n^Z_F?4^>vv zP;s$j=(3U;RK^&9Vp%E_*CegDP%dbL8?NOg7g)&OWSN!4N^xajt+>9*Am7;)hE@t| z*ZD5Jz3PIw<#ndauSmv1L1K%A#UfL4#kF!_iJ>J(X})jScQz*tF0E};7B*II*m{uB z*>YJ5uI9^GsfZFQ#kD2ZA8Rl!+9VrBe05``T)0^bTV!6zRW4zh0Nxl|6s0%ny zva$_wj{=NbJYp>zC6O%*NM*5AXJ2`FhDadGNaPUNZ;{EmWt_K%*@ccf0wdVfiRvT_#r_4PX^%Kk=)EiXtq)C~{lEO+{ zX9S#xkT53ggt3)Yb0?l6z$+c>MN;W=pv#O-rmBS5pAVe%bKY=Z2} z9(At{4FrUwEDQy^WV%LOw9D4$DixE(=Eqoae2vX`6YFX}?sK9j*W)KXKEFXok zPBCYBnvFTO7LBqBReM*OTmqcd;aM+^g(wwb(5j5z;Yf%Q49NH~Ze`K-K*tUchmNB* zAiTd1=P~qj#su@R+EQ2?ArcDJ9ty{DYb`7R-`;Y)%iWZKnvd`^2^F`uJAf7KF^hQJ z@brllRoaJ?RvJ8nJdO`3B3y*9D6i2C_WYX$zH>hgQPi|S<;|^am8|Sb(GMnCu(#Pb z)ZthcF|%dRA`b0H<0Y->CAxy^o8ZHV2iu5^0UfI<`Wr#DO`3`1=Ukf5tT$M(Fz!@| zDCV-EhoN`0$6kfREj=@wzqrJyO<`EEEA0cTstYy=~xb?C4G3kL9SqTk_A$3y+UUVdjar+>&mh}MMYV3@Hji4ihYaw$VD(+ z*!ZwG3r$^jxF8(pWgI>xW9aE@K3^(BCa>OrK}~hQNJ8mGKEHtNuf;6HXe=AM;L*}3 zvVyI&1)N>1V4rQFkSjB|xUx}NF03s{7&f?#&=}XvdRx}U<~K@j+n}rIqONi*4zpjI z$*mMiVMLZd4s$Y8Zb2}?b_v6@U=-Tw*CA%e&Nie24um00Jb)PGvNXht(QLhglO?LU z72DQdA+8S7W%FzjEQU)5z9t9B!8%s+BPN`g6$LPg*fk?Jo z$W_YgdFUw%Z?D-9*Ck)B2w>fMtmaqY61Ihk8NOC0PbFoN^Woc-oSiGKH&Sw{-gM|WIB{$%E!I&%a8&LJ={j@8Oh2SK@ z=wcRy!@QN^ThfF*r@?wl#o~f~PHYlU3sXk}tIXejgUPk6R{_?XoSES2T9EX z4_wp|y|=auu%<>{2{lOet=ySG%SbRnIy-oHFU$es0cY$~c15YjP8l}5_qgXJ6s$q8 zJjn>jR6R*rqSM6|CVa)F(Q4hU(lUUz$<77dq{`MVc5>-zsx+$i4-Ix(-Fcp!RtsES zj`nQ%?dHXUrl5G}G*vtXnTYWSVXOi2&|P~JvMMAMf)EHG>%UUK4tjQ_vbM2mh#?XH z+QC+k;ClW>3SA*U^|Roj)orj1uN;oxiN6H8PaA3!(~woW0StjwEOh)Qt@xY;Iy#Xax;R0KO9J*w^8kpt^{|zgyJR7UT&R z-@6?!8CjpbdJ|^8&Zy}EEQaG54Rzv+JJC+FwyS0(4xVkc8mj!|vBfPc3}^#jX3@!pFP>=T`(&@&HpQ5fm_5_!7t{&eo|+dmJW&B(~W=I!LbGC2PlY8XK*?o- zZm`n=1Db-VFLB>G`duj;tmsLR#;ox}7T_FE^gXf36SBAR1v*yeVBh0bx0%v;{n|X3uDB3J}VrHZ!PVThpn=tS@1M3dT*6CtE&h5@% zwkB{7O;bA#`qk7BWJop-=s-ZO7&5+jIU-|^NW}cA6?0#YhF45Sj$k|JW2+fkE_!xf zj@4uSjg}MJQ{zIcz_{`%ga) z=v=bVhs^LS04tiuvYl6$crxWvZtq?KUzU0B9Sy2TqDU zZ?n(YtGx*?8te30t>Qe!q4R#jX2PEF{M#Sa-{3N=5qNpWAh^y>?wEK5NfpruN^`$iQX(vYPr^rVrk^rq=XLpMBU*AvIs z;j7|a1d6DZ+}pxxr-qXP*}eKs)zI^KbFV`Jx@T^#<`B%nkgP+yESBcLS-0S^Yk{`k zv7gQ4_Oa0@ZnO?g;;iBv|4rB|S?q8(*Xx}vb8{Q+vn-8oAV{!!2W%`TmSE{%r*02z zUY(i2^Oj5(cC7Fjet!2o(kDU;`L4#091Tm?NOOCx5~Pz<0R|+Tpf}z|6{Xzf=+;uNA=}r(yYadzvL<$| znU3QS_q?ppgiz824aq!{kOL$aGdq7jbt}*w!wz6gl-O?H&>u0 zOCK6;y4!(oKjlz_2$GfjMkg90Il7E`7!HJdU3!DGs}Y+00tSoOl4>=Muv?plGu?Ky zqVpZ#zM24zYWvxUUNI!37EcbFad`?UJ;e|@U<9|=V2_u92Mc_Xl(MMC92q(pmravZ z<+)?P-NFz}>Oly*tiqP9v(7i6*c-;dy+9Ih_Q;hQc41`S7N09>BKF#Ngh?V?Wp_^l z-0J&!ZNeoDk~Wyc<13;Z3Tq74jl2^Pu9XeS@`yh`zjKn0Y(pmp3vt?Xmun$KV-+O$ z3WuLzK(D0w3+2zwI+hz(^l(#_%*0->6n-8dsNjoQB&dhysp%ya6%an)>Rne&zunMY z!B<2tFK#P~6{9lHu~XIZqzpH&KpMVb4G0a($CSJHbOAPqCJQB3OjR%ap=YtW16HS* z!~?xoL>$=ofVtbr*Ra9L!zLkhG7o1}BwjHPDt2|l>9{J|r~o%~QHRW`pF44PDCA5% zTuC{SH08Kagk3~fg{bDRe-ueYiLb)3wF8C%B$fsw!ZE{(Az{igYPb?1{}I=vHAu*r zdehh%OoZNIJxS81EFb-I-fGr{eH!S?UgpxWBUDIYc=)0xvLuvB94FN1_#ja}HX2xJ ziZ{NKaPn^A;iP*f*E5UW(Q;P!Bww~ZfTSc`CgD(*MFa8h(|7C7HqhNJjK?Rn_A3R* z{Q4F)&Vl?P3gO$NNYnVlHx}n9GS>}zwaN=t`%b{)e!y#9b^yr)?Z{HlRT+lrVmN(k`7k-Vi4EVM@1_V{LN? zu52{J3$Ccl0>!;_b)dIXCEegG<+xsTUCC2^YHCzu`mhL_P-;oho}_xmewo%0?H!EH z@_jZ7_XF6HJwq3B04Q+-Jw%m^ocUxm;OSZ`f|5SXJ7VnTcg!;Lt=gdk26RD$;s#FS zlch)$G+}e(19fVjGBVi)S`Qjkn7Z7Qan*G->@iInAq=6!2s0ya;5yJnK)|jUu?e!u ziWh+i1=`ku{qmybywBmS6Z&Z$3Rp+neO~#cE{J{Z)yODq>yDp*GCZ?k#0qH$@h<4; z5(bK|;r2`V<)ECNxmlN+Btom-RdE+7$z>9dc5=B@}mr}D*DQNJy+_)3}|6+Y2%D@e;q;^x4G;_ zhT)py2&>J*L3MC<+s=X70Ryt3;bXt0Kf`MOI7m~Cz`}J0?_&-3)(onq+i(NtT;^#H zU&n#at{|rX4%3b`U2;SFhxA7q2bk<}c38y?AY5 zcJbx;#hID+M5c4Z?o05RpIZfo{?O!>Y?Y9lc@~}m?zOp@tJlouKBw-`nR_qI%*#AsmxutdiHr51QPVrgFadXQk`@8H^cE}VR(=3=evY_>i!~^W@XZnL zS_J#T6)6KQu;8gaxn{N1q6^sE;g_=5$?b+L$yefiLOAw&V)Hl-)0r!T zsT(DvV{sdouj~ZAJD2BEmT)-}J~O}p2_BaPzr?p0HBtDfT;Q@G{6GWHXZ9tWhcvr& z`~>v=tii>&4O~uvI36|p)n_Tv`5EoISOADpd_`+8SJ2B!^$^(T7fIvSp(V)2xbXFE zD0-ee(b<`~t36Y_y8Q~K8lV2v?JCmt-Q6hmYLvb^PVgI0ExoX=1FZuR4K}3SR{|jL zz$DaYXl>#NGI8bSjPwZSOWkcXE|FBGeYTBjs zVCSGw1%k>FfQ9g@pB*Sr@+^uG)WMNan(&0EQ~C5Xv{Q4QD{A4V-&Y}8y}`8 zj!2*uJ#HjNM{x{W+M-6qk8W^W#HP62PN>+sG9Tc(gn_L@XQHdTf#UF?fNX&88bAq% zOerC6fbvOI;7H8{9|%zc3CO6x;G~B9oRtngI04skn2n1G?=-sK29k zGS&bnAhO)#23&|;C#*J+h)s~YdeX~sfsUxrYdAZM&H+^H*XW^L$YxyBC*N}el+Ybc z!P2=Ne4MG(fRFIk0TNZL3%ab=LjRN}!7W^I9USTrLU$$@hL0W#R@(~{gfrIG^PmxH zA?d!3T#Q)X@@?v+OE~;<&t47K-r0nk%HV~oJ}^CdSq9p&t%CD~f&sUBx_f?12Rn4? z-MAZGMFEW)j&!rWy)}33m1_%N#&^`jFzfYi;3JEmfvaS}eDSSEeSbG-i*_9?2AtD2 zdH&nq;z;yh3Z@R9IVo*3G<^FmRp7S27K+&KGF(%PGMwmT8w!>+xmnRlFno~5Zp(FC zrhVG#&h)JA?2B_)-A%bGK<^ENWdRk4V|Ticv-IItw717XaPzt=lb6%O{H9#KGY17L z)6lClt;Z#@3bJCHt$f0#Wh0pG7|kJof?G6ke^Eg$pyrq1SOtKa^vjs%RHb0Q3Ka=1 zT;3*VPe8F~*q9hT1dja{p52Cw++I5n*(wrwDwN%Z^A%#i@v3YoS17P$%fHC@Y&m)1 zQ#l+!7xGmz0_7l@X#oHQKrv0$FnriFzND78-aB+LNjau_?kwZCV-F`Kd`SICVVYoo zz1u!uOHR2PcVBO7;{9GHd_(E-?K#=i}Xipqn-b zOgJG5cy38JP-;Md2v-3cWtKxZjw$1Q8(*~P1fcoozRCj3a1LS_Fx4zvO9rmYG*|*H z$OUXp;C9iwxCl`{9S7eN?hAd=aQ2qHDE-+;w*|9^P7&SlgsKOU0XM~Qpl$o{Vh0}~ zD$Aleub0B{fG^E{>J_*sAK!Y_{8vB9%uXS^tG$GGb$e@o=-;~7%YIqzN)OR8tzVVc zy7;2m=An12Jue2N9S1cIeEDQ<|8lSLHTMd+{mB)eLB-V-R+z&%=rWEs^XL+6J^emT zUl!&Xu@bxi(W!C*dOttBfMVdjbpVIKi6h8g*A`XrXjt2Tk-Ce|gwfe)W9=L4)oso$ zJ^`l9oz}`+|I*b4EJK3kEE4fcC&?>?b(bg@G2M7!Hj~@BN0QO}Y{?QYPbx z5@-pU@bT~rG0lkR5#rtx#IoHZVojK$>}~575SS@0o1^y~BvokQmTZW95S4Z%qrhfK zoE3odt$IK8@SoK3Mx?UG!V=Quo4U|Wu~4!F#;{HqV4!9xWq~<*8o(y-AOq95wthD~nkv$cb(zQm3oI@l zEIOQ}@6ry@2U&VogdvVTpqjhb9ruSd^ono2p6r@Kn^bKan?R887#{tuynNky zIF$MO<;U&}zRbhlwXG+pW!)MwRLQj4K2$-EO4c6y7_pSl|) zFMY!D0|$1mBjQmvavLfEP=G7d?t$pJ3C6eJ8KF^%!CQ|Rs33B7or;V*vg$U2f$8VHCP793agOwPU&56!3@F%^i4!4JF%D1R|I#@AMW9?Cc;W z+$6N%i4eHZnuS2z0PPo@#t!0I4OzXts*mPKoHiW^>`K0GdU$0R|EZ7>MTZNV8`w7zL)m zlDVw{5+t#yq(OCqV=MW$^ol*inFmUB$2UnBu&72fyO8Z}2-h_~o8` zl!6T#DUm^13zDdgv^qjfw6KM`aGW64MQjsoWl$nO%q%^)y%I_W_{E@1*g^-r?n^(w zQsmW)dGq1g>6#Uk$LGwbw|jbvg$K9z7U05paz1W$Ki}AVOY^{^2ex=_6A;+Oe*s2d zo|)$z&wxh;kf@?|6(Q!d0deGio-1_+sST8>ArH4%BWFus%9Xm0(&jBc-we{++H$4* z`m^1pw9!KET-g?|VjsPLz+_F?ezbBiqCbduO+cc9<$~ zdgb9pvW3}f#UU8MuA*T4FO2sQ>^ix{hr)b(0_rI8^p-vb?myIg*DY)x3S%E?zOKbn zsp%XsZ(DE;{NoHUkXVB7m0~34vf!rXWTXsvk78{bI6)o&tiR%+=Su0?#<7@Ojdkj1 z)qH*sKWn139h4#0BlenC9Y-KFMyZdqMU1?MbcS)aJwh>xevY|YC_~=X>B;5DEX}@_ z3uix=%Qnyg=`w>}c4Y<`p>}cxGdpM=r`9;fv6iJxz`L-Daj)!n~(5Vu9QNtg}PjUJsBrP`V6@ru1v&JVZDqTt}r2q zxs6lOiHw?#%N}i!yjND^vD*mY7nNjARs7`Nb%|%B9WSx8mcuQNSLO@z1Gu^yH|G{9 z`$0_NvfbG@Gqhzd?F@8pukYUsHzLehDhrLD?zE`#B|*BAOOptKm29{$`TZu zN>nU5MMx1tg($@genujk565}VOvqT{Epsjev?@*<2~)_vYM5Q(6!Gqt*F4AeR{>9= zx@&9Jyo9hW-xa8Im$2kqJdY}b6A6-ah!{^8IJ~DkVkr7iXu`OGbbcE7IpT} zW`EiuAgk!(5!*aNAy0zhDEo!5nPMH>P=QjGwR|$lSW9SAl%44flp~WROHwvO)gg}` z{$4a@gRMtf8QfdO+yLx2OOKNd{|2ampMNNE{?^0x&DK7KNH0EYyIvLb)HGl=4?Rxb z-a{!0Z$Iof=P`d37`}&7NBry>YLI3~tE6c16Sr~{NQcI}uz(dMugO3;=33rG=&lGX zrm3hVw=tKADx~6$9ETx<-vGZ_!kfw?CoGGF4vHSUzhwI1lOh*-j5h0JunnN0OoP(o)Qn9*@ zT#m0TY81z(WeM9&p*8Y(ZD}y9GvlPI>V#D@&0_ zW0s>dulrFr(}DCtAxTw8RRvukuCPiJUFD4VtT9i27O74$sA9qyA_o^`upRP!N)=UJ z9VW0$Z~G1|vGHASJo6;;z`Wr3d7RRT`)cAUcAKgA+F|yyIT^d+Vmz0#QWpYiE4O~# zBz|Q9^YQDC-5`&7G*ZVoLs%PZ$bQVyKI&6&3RaCU%!;kHuxcS>3uf31K z&)<6ZmPt{hfrsM19|Hoe-BTgD_weKN9KF9~o>?LPR83G7&jIWAvTq|Q72-jDF_X0I|HA)Oue#*epMUg=u}p*4A(vb$JaafDefMrbjZ0< z4v@PJDxq2X$;SF$2x&&*J&Zc+cTSx?Rd_n3A|0Hzzo|sK%^v8uz|o z9yAV2$#Z|so?0CtN{IB?K?rol?G{D`6@{G0hinet!=Zs@~q|Hxi%`8SjX=j}k zuaioNxg0yO*TFDq-!xE1v58!i+B18>0dQlsezE#oQ6~X)@C3ztag<qBYls}FADV`%94(_8ag z?Nt5w0b}y5Jd}3-0yjiX@_Uiy99^1E6GPPJz!hLU(in9~^J3hpCVL~*+{VhN-8)dK zy>_~kqSR46)ZwuDNhvMhnOU8ezI$v{9ckNUtu2kfH|XfgtYwWOXe~> zkeAIH(13LeD}X~2^D#&Nl~*)~{%nxW2{H$&Ny@TjgtaJ1c~Wq!DazEMAjQw03E1i) z%C$|Mj;k3*`@1O3CGbW$jf^H7z-ofW3A;}rDaKi?Q@6yp_(KZo-;8UHQOQo{VEsnEQ$nUs( zYRRgPf)H^VBh=~G4neZ?@-eOg*#^p8*+f4r ztSOm*j;eP}m8tmp=9L1d%E93c)6AC*lwOebBi zfBu;lD5o5MrwoZgDJna-DIH}<#4Ok136|ECIAc?*{{eMgj`q^ajpFpbX~#oN#8i6W zw`_R@{l`t&#p0~Fro)dBk$H_6;%#~EVRQ4GYDDjjZ^>eX-`qEOEv?)0 zC5)81I5|vw-*!g)6|>M~t|3?VZ|OyRNiff}{H(ZU#6tQ2i07&@C{R|nTxK{!=7=4=Ln*u7eaWfp#KQ$pXi+zdVD|&@e!Km;=G6Oc3MsbYeO&Z6?%GKxrs3} zu%=vFovXuLN>55S##Nz=9v(79$_7$`J7A(^oqa~tl>TXjn9e7IUH_^`32GEvP2!@} zs^9)a+Uw^xk(S3D-kFy@#G?=)9ud>%MI?UHuNB2LQ&kO!Gwj9xsOF`yjave{f z=JhxqCUxkT;}*8c74BuZ)^rx;qT?reKqoGZi5WaZ%a3>oWi!P&G32w^E zyiKp^hpj%QoWNn4`GUs?^8bEm&UK?^3LW7U;-YKGQ2=>}=bKD*CwT&o#jmqwKQBH> z$BknFG^tnfmQthMWBm3j{(@S;Jv{hgBav;v%+|IfBgL%Y`8G}+$7ceQ9BfC>k9J}&`jEqsPsZ?dBZnnYsol>*E(3{qoWDOOzKDGs zs`c}>O6%#tT5?~1v*fd0+wPxxUyZ$AY%P0X>-2WF0_tI;1mb#_$}*r#nX48&wUdr$ zPF&GmJkb>n;5VecMZLmlYU&YF2GYbnmGh@3-u(IDt)C?H!RO@yup(-0IBBH%P~3WR z7(`pqN$9AB7}dTgBZ=v13lOhOaN6kAS|prK!$s9NqJ8%D@?yVM*~@-NA6(hUPC#yO ztvHsRF8|CkP7`uEd7N#UKkwym@2FJ=#SctkRD?1|?4aFGm7Z5U7-}rbEkMew|Lj2m z{r{I?;n+&QT1S=DG45Fi-8q<;W|}gVsHBGuNZMrSdX$+?SyjMGNDWWt_c$kbkj4?7 zA~$>D1`wZ@VHz$%X(CvoJ;8Bfl_Bp?h$B0d3oaR38DyAnv)LPPiDw5hz*W?DP6G3U zLx4lCV!xQTOx(F|y>rVWHKECT2M_b<8X!is$UA!+s+yN`G3ZmNS3|@19#y3|YjGsK z5FH7XPi0_Hp=*uq>tr#k)5cqonPGR7HNN`M{vE52%;atsEwL?iDY=n(L!zH>`sc1p zTMgLgmKDti?-XWBPSrIB|1SFtd+q$Y?3F4JzD>fhWM|w**{mup16KDkO{d;t@WdT& ztkUcu_7O+S(gH$EA)b+5odQOzRWa$QSLu+9npB|-TQSXS4B8ANRqYGzyKNTIB56~1 z%7{7aL)Cayt<*$TCTU*gY~nZ&7Xfax#CAuiFaTeVLd~t;Wtpd&xfeDAL}OvlY*>@? zAvAkAQuO#r^jK5kbw}Aw2sxD{KC39lU61r*UOkB)^a`YYx-!@Rb4ThoVtkgoi7Vm8 zLY}L$BK3z`P}qt)5pQ0PI|c|%k5z--+{D9W zSD;nW2vsCK4(eShUMY;4P)bwL^)O%id0KTJZ4ooPfi|G^&%2T(!5+f1pT-Tg#Bc?g zK-?gV`azZ*@wav5QqSklSTo<`V%BM4#x@NDlZ4hmGoQOC%AIphe%vIyZdnOy@0W0WT zIco1Q7s{kKC*l?(k6D{DdeB;2g{viuk!!`)d8CzFnS@@izN%EIpUF^f8kBF&MaOC` zEBEZh71hR6Yo?CS#{3RBvyByu!f&rQ`Z$d*IV~YhLs5OtTu{6`rGz+xJq8Ad5r#nZo)5n~C>A#L9-4Y*l z4SV^q$@X&D=vIFG3w|9#@7W~$20D812S~qwo>-DNt(-7!*TuK?ou+3lavafP5mDN$ zBahG{R@BS|9JMJS?lxwb9_VM|orz-NdxJ&gu zR%BmzwdZ-BBAx!~Wt48U=+Q0RM%#ve;^aAlB9MEEmHccDklw?83MW!({4fGqz`tMr z-M{)Df8)ZBbHD!gKYQyR{;U7ZnA9KK|LV=Bum12qOqt`H@T_F*%0F zWV$di#G=D|jPjAhV-)%6bEq-Il0yhgFff5C6BARb$;@zKdNh?{+9)C^Mo@?e5*TJq z3T-APO)@c^lK+NNDU5z-cr5)nj0f-O(UGxf3~US&92*}R8y$Y$4B>AAgU^_ek3RZ; zJ{oz9Lz>{@M`(^iPM=GS;+0B`VH9W*k)c$I0Gb}2Mts7IvPbqdW`;-c4?PXzZwyVN zbOJ*k`F}q`iyz@1(#J>5(D?W$#y>eUHi<%j%y43IVge~=hsGw5a+W<#0vIM;z;FvA z&m+LJ^G|U|=hI)B$c&`l#5=ulUV!(ereC$`SCOtM*KEqQFy#%K@`lt!KaiOeXc z#2{ud^)+@e^|j$KM4v}AX$aWqQN=SZ=eSYSn;v}(OGqS~9!;-IRnJd8Zc?#0mJ1^o zL%*ZbgyJYVWe`h|85Pt(cr;_C(*e3hI5U*KzyhPsOB$Y|BadT=Coouabo5(O^^q~W zFo6sB+e>9e5|gMmH1b!T!Lp@L6m78R@%eGBb9|n-H!*Q0Gn#&rT?3YAmO6)a)5o_aAD6og_%j$Y9$)9vkTa1{v< zj*mAGm4P4qgY?mdlam}kTEjYqqwkFY*6E|~$$FxQMt`WUA14j+{sEBM4Cywn40Up}f53oAtu}~Z+ zF$O4^K(8NSaneUW(2jn9@nKnxJ{$u|Opi_qW*q%Mdj0`c3 z6LX0xiK~eh6E7uRPV6M^C9;WyL_SeSTu-bdRugN9QsU;>=;sHM(Fl0Q(SQD1XpGab z^Ebm2TuJc2^Z^4P>{R+d5NaI3NgEnLqLv#;5lc{EBqcQg0hHkr_-=siBxOK^tMN}| z&L0w#f5eA`{weYZo20x5JQn>>UdNgY~%@cHN{7o50rbH)Iu;2VIV6o`_wp+&;mfiHJ%3J)t(;bWTsOiXSD9o zPtm~9AG4JVAD=@hpvO-MDv5B87{&?*DBN(W$`+=o;3HM?k*c=)JQ?NJnZ+k6U(@t! zGN(5fnL2(WMV2%2n3BktI-W@%Uqyk(Gh{qI4#<*3&I#gz zj2Gi$zfQD1z9zuMsD{&TP6{i=ghACK|z zI3Ghhcx3pvz()dmX%I+wpn;VUV#bI8ryDUDJg%_ii+nuA2i1m=Pw{c%`tS%I$rK(l zGk7G1@E9B8BZnzV!8NJk!SvW4*QCZxdr~Nx$F5lev7}0#2ZV-<&){ z(a(VJ`>EsKX8FG98ysevdW}i13XicL*z9OWVd7*)Ut+#AWnt= z#a~Mw|JFDZE@Vy}e+MB{{V;v3;^f$Jr4LlXA1|OGEDvC>!}{)|2&LoiG6^F@T?vXp zmn4wK`8b0CrO<&E{(xfsEUEBVf)nIj$o@bZK-%LI6X#t1(Bl)2bHFJOF30x16od$u z(Bo8}lK30P-x-kjL~4RMTY~dJ1$Ko{%Ao2C2mtQ@h>6j$X+!|QqhBQ$KjhhjodFB=?{F!9k1#!dUO>UZ)P4v69pHD7q@i0jgc=CR!v7xE*#&+Ind*gF_gb!LwF#* zUdqmbRZtY0|M73EedlMtbMV)G_@h6a{*B+A9sbFM$;-d-A3e5M-}*bxe)K2*_kaC6 z-}|+{{!2gphoAVr{_uk*|N8a6_v)u^{=q-L_?4Z1^dCI^8^M>){r2Cz`mg?z>#bX_ z4qckK|DC@%^T)~m^zwhXJNA>G)&9@V-1|TNcH(dS)o)&TdgtjsTK(O>J8|*+pS*tm zf9n3F|L*4f;>gXvwY~Gnm7T)xk3d^|iVx^sQ{RLhiJ>2Tf9mKT4MEjUCQ>6wsOw-( z!}ym3{$tj6zjL*^0)L8?JJ^DVR)Au3a zk|VSNM$aaJZtfpPa+VD6{91CJ?GN||ON4gH7_-LYUuq2h;UBCA3>9xS932{BNhy&^ zJ&}Bjnfh;fD#O6j$xrYl#*d#5lSY$lFPQ`<#>^&@XE-G318-Xm5?pGsy!{98iR7L- zo&pqMvm}Sd$H}I@`8cx9CX>VI@=*E>zHi|T{+nJ-U*+qDz82D7`c(4V^duNhx{xlw zP~anl|Al0xjxV4cvWQ`@RR{$_a|pTA7E|ZPABQe7{TcHaXl99FGOPoL2_WVRQ^yxm zh#q|(VU$0MWt|>QzfH|-cmhqNkEheGr9aQLnM}b@Ndl>%Sc1WW#UqkFd^TY|v(X7M zdHgateypX&%dBxFF0L2O;LhGIulqM+$zhb7U~Nb@t1Q}wgSaSL`}94yJn z^XJcxQf`91fUPi5D18HfKx8sGnm%4lAH({Ek@0ah!Bu_g3@~JRlrx+jeJ1%7QArFd)B)b0bodWFVu%9G9>V01U{EA&k*X}-5?`BI8o*ghVbVnGWbaqTq=$G%+03~W{QR6 zx8D3}NShxLO@>Lk(AGxD4Bw^1J359P3K{txKqWf)Cz9t-0IMf_^H4@U39SU`2B7|{ zw0K4Lz!WAY{}c;D??wjHJ*3kdNznksI-vNk19wJP5QvmW7l8NZP@pk7xr~ohT3wMv$;LYHm|sn*`0ksvieJD{MeL(`=IK$g8sZT7%X) zo*ARN1ph>)Op+}e{QyeZ$OM=ZT7+#yikJ}81x5U38R>|=3xm0pgICARK$xnea+&^+n|8FWu1`tiM4RIzQ6Qb^U5mnE#(JxN8 zp^c`VOg<5B%eD$eGL$Y0pA`lxad239gT-=U+F=K4G4XWaDab{*pk`{X(xV z=tx3t)7PIe3%noxXDvmQ@XLcu{2s!9B5w4q2rp+JP|Sg~7ZCR1dEaHo z7oyM@(BMqMe1TJZhZnb7aPancH`%_1FDA_M0+VRN3;3nGE`GU`Q^$`a`e9s7m_OYM z?eMnv0mBiN{2rJJ`2Bwa5s*IqeR=-(5xLQfv=5pdIs>X3hw73X!xL{87^hD_sSKhW zjAyF)SaKX{uW%cgP%&o>H-b&EEtf&+{L`2f=P)^SwkY^dn#eh=J`{p?iZ7d zkn&#^84FTY%6?zK^ZRhGrYHuFe;@Qb0mCGH4iAx@=ckjfD1H-`9!T|gH~mG*JMhor zpTHnU7yeZ8i6L0U_%{xNK^QN{R)(x^Uy_6?G}8X#~;vgNvY}u zwvEPwEu1IsIlje&Z@~wGu}DzV4zQ-LbB<)}6G=EuF$#1DU1h?B*~xjb=1KA^IBb6p zlb8e~&q4D#2m9_PFvu}K+C&rJw%9WeT@}yC+Yq~e`^ zji%Y>IdcBVO8jKvmy*w*y)$RdOh82%nm987VF76(5J`=rNf>OH)h9937obgX4)`CQ zWXw!7ET%%!VlR2epeQrtmyG&^rZG@tIhf-Q&<#Y`Fq9B^;SH9Goe(S?EKKCkZv_pE zek|J3me-$4Qu;ubIVL7z@&MG3bpI_nCIJ{~vlA1OFjmH>ZXyo~5BWHtjzywMh$&F> zg{(r^N$Rz!VQq@Vv4kj_MDgkK{12dF6(Aw{dNPR~+)6WfBaLM6(`%VaYx#0!u?>BPzvq#e;|x*>dd=_;!Y*OTL!Wx9 zUEN=6HN)T4z^~Y}?sgK_KBDQY|JE4JxLExCMp&+r!w*U~@Pl{wxzD{0w96p4RBPbk z2>ko#^Ct6#g#P__Bj9CI;Ap#m z_DVQaz&YS1Wps%k7q* zJkP=7zJxOtJW)!-#O3C=l1I|*p8`AnF&#}iD(e5$K?iju!#@EbQ!1xB*=M^Rg!0oR8S^@1oYp)21pHeb76PN6(*NZVxd?B3P z5d6vlYCL7cGqQR*^0azUJYyS={yl=gBM3Z#z#|Aeg1{pPJc7U@2t0zoBM9_B;3q@S z>W%rjGq`)QA4MNQ;1L8KLEsSt9zoy{1Rg=)5d + + + + + + diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/link.xml.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/link.xml.meta new file mode 100644 index 0000000..7dee6d6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Libraries/link.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 843cc923151568443b86e022f705a263 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization.meta new file mode 100644 index 0000000..5c40bd0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d1fd84244cb36db4d99ee03b6d61b246 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationHelper.cs new file mode 100644 index 0000000..7caaf09 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationHelper.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Localization +{ + /// + /// 本地化辅助器接口。 + /// + public interface ILocalizationHelper + { + /// + /// 获取系统语言。 + /// + Language SystemLanguage + { + get; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationHelper.cs.meta new file mode 100644 index 0000000..c93b133 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a6a8606f5a51d243acbf47da824398c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationManager.cs new file mode 100644 index 0000000..abaec56 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationManager.cs @@ -0,0 +1,504 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; + +namespace GameFramework.Localization +{ + /// + /// 本地化管理器接口。 + /// + public interface ILocalizationManager : IDataProvider + { + /// + /// 获取或设置本地化语言。 + /// + Language Language + { + get; + set; + } + + /// + /// 获取系统语言。 + /// + Language SystemLanguage + { + get; + } + + /// + /// 获取字典数量。 + /// + int DictionaryCount + { + get; + } + + /// + /// 获取缓冲二进制流的大小。 + /// + int CachedBytesSize + { + get; + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + void SetResourceManager(IResourceManager resourceManager); + + /// + /// 设置本地化数据提供者辅助器。 + /// + /// 本地化数据提供者辅助器。 + void SetDataProviderHelper(IDataProviderHelper dataProviderHelper); + + /// + /// 设置本地化辅助器。 + /// + /// 本地化辅助器。 + void SetLocalizationHelper(ILocalizationHelper localizationHelper); + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + void EnsureCachedBytesSize(int ensureSize); + + /// + /// 释放缓存的二进制流。 + /// + void FreeCachedBytes(); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典主键。 + /// 要获取的字典内容字符串。 + string GetString(string key); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数的类型。 + /// 字典主键。 + /// 字典参数。 + /// 要获取的字典内容字符串。 + string GetString(string key, T arg); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典参数 15 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 字典参数 15。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典参数 15 的类型。 + /// 字典参数 16 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 字典参数 15。 + /// 字典参数 16。 + /// 要获取的字典内容字符串。 + string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); + + /// + /// 是否存在字典。 + /// + /// 字典主键。 + /// 是否存在字典。 + bool HasRawString(string key); + + /// + /// 根据字典主键获取字典值。 + /// + /// 字典主键。 + /// 字典值。 + string GetRawString(string key); + + /// + /// 增加字典。 + /// + /// 字典主键。 + /// 字典内容。 + /// 是否增加字典成功。 + bool AddRawString(string key, string value); + + /// + /// 移除字典。 + /// + /// 字典主键。 + /// 是否移除字典成功。 + bool RemoveRawString(string key); + + /// + /// 清空所有字典。 + /// + void RemoveAllRawStrings(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationManager.cs.meta new file mode 100644 index 0000000..1d91bf6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/ILocalizationManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c9054927f75d144a805e7f7c948a425 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/Language.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/Language.cs new file mode 100644 index 0000000..ae4f929 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/Language.cs @@ -0,0 +1,270 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Localization +{ + /// + /// 本地化语言。 + /// + public enum Language : byte + { + /// + /// 未指定。 + /// + Unspecified = 0, + + /// + /// 南非荷兰语。 + /// + Afrikaans, + + /// + /// 阿尔巴尼亚语。 + /// + Albanian, + + /// + /// 阿拉伯语。 + /// + Arabic, + + /// + /// 巴斯克语。 + /// + Basque, + + /// + /// 白俄罗斯语。 + /// + Belarusian, + + /// + /// 保加利亚语。 + /// + Bulgarian, + + /// + /// 加泰罗尼亚语。 + /// + Catalan, + + /// + /// 简体中文。 + /// + ChineseSimplified, + + /// + /// 繁体中文。 + /// + ChineseTraditional, + + /// + /// 克罗地亚语。 + /// + Croatian, + + /// + /// 捷克语。 + /// + Czech, + + /// + /// 丹麦语。 + /// + Danish, + + /// + /// 荷兰语。 + /// + Dutch, + + /// + /// 英语。 + /// + English, + + /// + /// 爱沙尼亚语。 + /// + Estonian, + + /// + /// 法罗语。 + /// + Faroese, + + /// + /// 芬兰语。 + /// + Finnish, + + /// + /// 法语。 + /// + French, + + /// + /// 格鲁吉亚语。 + /// + Georgian, + + /// + /// 德语。 + /// + German, + + /// + /// 希腊语。 + /// + Greek, + + /// + /// 希伯来语。 + /// + Hebrew, + + /// + /// 匈牙利语。 + /// + Hungarian, + + /// + /// 冰岛语。 + /// + Icelandic, + + /// + /// 印尼语。 + /// + Indonesian, + + /// + /// 意大利语。 + /// + Italian, + + /// + /// 日语。 + /// + Japanese, + + /// + /// 韩语。 + /// + Korean, + + /// + /// 拉脱维亚语。 + /// + Latvian, + + /// + /// 立陶宛语。 + /// + Lithuanian, + + /// + /// 马其顿语。 + /// + Macedonian, + + /// + /// 马拉雅拉姆语。 + /// + Malayalam, + + /// + /// 挪威语。 + /// + Norwegian, + + /// + /// 波斯语。 + /// + Persian, + + /// + /// 波兰语。 + /// + Polish, + + /// + /// 巴西葡萄牙语。 + /// + PortugueseBrazil, + + /// + /// 葡萄牙语。 + /// + PortuguesePortugal, + + /// + /// 罗马尼亚语。 + /// + Romanian, + + /// + /// 俄语。 + /// + Russian, + + /// + /// 塞尔维亚克罗地亚语。 + /// + SerboCroatian, + + /// + /// 塞尔维亚西里尔语。 + /// + SerbianCyrillic, + + /// + /// 塞尔维亚拉丁语。 + /// + SerbianLatin, + + /// + /// 斯洛伐克语。 + /// + Slovak, + + /// + /// 斯洛文尼亚语。 + /// + Slovenian, + + /// + /// 西班牙语。 + /// + Spanish, + + /// + /// 瑞典语。 + /// + Swedish, + + /// + /// 泰语。 + /// + Thai, + + /// + /// 土耳其语。 + /// + Turkish, + + /// + /// 乌克兰语。 + /// + Ukrainian, + + /// + /// 越南语。 + /// + Vietnamese + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/Language.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/Language.cs.meta new file mode 100644 index 0000000..887ab22 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/Language.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0809c6adf37e2aa498051908ca0f3fc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/LocalizationManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/LocalizationManager.cs new file mode 100644 index 0000000..7c045d6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/LocalizationManager.cs @@ -0,0 +1,1065 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.Localization +{ + /// + /// 本地化管理器。 + /// + internal sealed partial class LocalizationManager : GameFrameworkModule, ILocalizationManager + { + private readonly Dictionary m_Dictionary; + private readonly DataProvider m_DataProvider; + private ILocalizationHelper m_LocalizationHelper; + private Language m_Language; + + /// + /// 初始化本地化管理器的新实例。 + /// + public LocalizationManager() + { + m_Dictionary = new Dictionary(StringComparer.Ordinal); + m_DataProvider = new DataProvider(this); + m_LocalizationHelper = null; + m_Language = Language.Unspecified; + } + + /// + /// 获取或设置本地化语言。 + /// + public Language Language + { + get + { + return m_Language; + } + set + { + if (value == Language.Unspecified) + { + throw new GameFrameworkException("Language is invalid."); + } + + m_Language = value; + } + } + + /// + /// 获取系统语言。 + /// + public Language SystemLanguage + { + get + { + if (m_LocalizationHelper == null) + { + throw new GameFrameworkException("You must set localization helper first."); + } + + return m_LocalizationHelper.SystemLanguage; + } + } + + /// + /// 获取字典数量。 + /// + public int DictionaryCount + { + get + { + return m_Dictionary.Count; + } + } + + /// + /// 获取缓冲二进制流的大小。 + /// + public int CachedBytesSize + { + get + { + return DataProvider.CachedBytesSize; + } + } + + /// + /// 读取字典成功事件。 + /// + public event EventHandler ReadDataSuccess + { + add + { + m_DataProvider.ReadDataSuccess += value; + } + remove + { + m_DataProvider.ReadDataSuccess -= value; + } + } + + /// + /// 读取字典失败事件。 + /// + public event EventHandler ReadDataFailure + { + add + { + m_DataProvider.ReadDataFailure += value; + } + remove + { + m_DataProvider.ReadDataFailure -= value; + } + } + + /// + /// 读取字典更新事件。 + /// + public event EventHandler ReadDataUpdate + { + add + { + m_DataProvider.ReadDataUpdate += value; + } + remove + { + m_DataProvider.ReadDataUpdate -= value; + } + } + + /// + /// 读取字典时加载依赖资源事件。 + /// + public event EventHandler ReadDataDependencyAsset + { + add + { + m_DataProvider.ReadDataDependencyAsset += value; + } + remove + { + m_DataProvider.ReadDataDependencyAsset -= value; + } + } + + /// + /// 本地化管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理本地化管理器。 + /// + internal override void Shutdown() + { + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + public void SetResourceManager(IResourceManager resourceManager) + { + m_DataProvider.SetResourceManager(resourceManager); + } + + /// + /// 设置本地化数据提供者辅助器。 + /// + /// 本地化数据提供者辅助器。 + public void SetDataProviderHelper(IDataProviderHelper dataProviderHelper) + { + m_DataProvider.SetDataProviderHelper(dataProviderHelper); + } + + /// + /// 设置本地化辅助器。 + /// + /// 本地化辅助器。 + public void SetLocalizationHelper(ILocalizationHelper localizationHelper) + { + if (localizationHelper == null) + { + throw new GameFrameworkException("Localization helper is invalid."); + } + + m_LocalizationHelper = localizationHelper; + } + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + public void EnsureCachedBytesSize(int ensureSize) + { + DataProvider.EnsureCachedBytesSize(ensureSize); + } + + /// + /// 释放缓存的二进制流。 + /// + public void FreeCachedBytes() + { + DataProvider.FreeCachedBytes(); + } + + /// + /// 读取字典。 + /// + /// 字典资源名称。 + public void ReadData(string dictionaryAssetName) + { + m_DataProvider.ReadData(dictionaryAssetName); + } + + /// + /// 读取字典。 + /// + /// 字典资源名称。 + /// 加载字典资源的优先级。 + public void ReadData(string dictionaryAssetName, int priority) + { + m_DataProvider.ReadData(dictionaryAssetName, priority); + } + + /// + /// 读取字典。 + /// + /// 字典资源名称。 + /// 用户自定义数据。 + public void ReadData(string dictionaryAssetName, object userData) + { + m_DataProvider.ReadData(dictionaryAssetName, userData); + } + + /// + /// 读取字典。 + /// + /// 字典资源名称。 + /// 加载字典资源的优先级。 + /// 用户自定义数据。 + public void ReadData(string dictionaryAssetName, int priority, object userData) + { + m_DataProvider.ReadData(dictionaryAssetName, priority, userData); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典字符串。 + /// 是否解析字典成功。 + public bool ParseData(string dictionaryString) + { + return m_DataProvider.ParseData(dictionaryString); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典字符串。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public bool ParseData(string dictionaryString, object userData) + { + return m_DataProvider.ParseData(dictionaryString, userData); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典二进制流。 + /// 是否解析字典成功。 + public bool ParseData(byte[] dictionaryBytes) + { + return m_DataProvider.ParseData(dictionaryBytes); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典二进制流。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public bool ParseData(byte[] dictionaryBytes, object userData) + { + return m_DataProvider.ParseData(dictionaryBytes, userData); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典二进制流。 + /// 字典二进制流的起始位置。 + /// 字典二进制流的长度。 + /// 是否解析字典成功。 + public bool ParseData(byte[] dictionaryBytes, int startIndex, int length) + { + return m_DataProvider.ParseData(dictionaryBytes, startIndex, length); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典二进制流。 + /// 字典二进制流的起始位置。 + /// 字典二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public bool ParseData(byte[] dictionaryBytes, int startIndex, int length, object userData) + { + return m_DataProvider.ParseData(dictionaryBytes, startIndex, length, userData); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典主键。 + /// 要获取的字典内容字符串。 + public string GetString(string key) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + return value; + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数的类型。 + /// 字典主键。 + /// 字典参数。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T arg) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3}", key, value, arg, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4}", key, value, arg1, arg2, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5}", key, value, arg1, arg2, arg3, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6}", key, value, arg1, arg2, arg3, arg4, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7}", key, value, arg1, arg2, arg3, arg4, arg5, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8}", key, value, arg1, arg2, arg3, arg4, arg5, arg6, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}", key, value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}", key, value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11}", key, value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12}", key, value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13}", key, value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14}", key, value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + catch (Exception exception) + { + return Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}", key, value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + catch (Exception exception) + { + string args = Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13}", arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return Utility.Text.Format("{0},{1},{2},{3}", key, value, args, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典参数 15 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 字典参数 15。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + catch (Exception exception) + { + string args = Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14}", arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return Utility.Text.Format("{0},{1},{2},{3}", key, value, args, exception); + } + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典参数 15 的类型。 + /// 字典参数 16 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 字典参数 15。 + /// 字典参数 16。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + string value = GetRawString(key); + if (value == null) + { + return Utility.Text.Format("{0}", key); + } + + try + { + return Utility.Text.Format(value, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + catch (Exception exception) + { + string args = Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}", arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + return Utility.Text.Format("{0},{1},{2},{3}", key, value, args, exception); + } + } + + /// + /// 是否存在字典。 + /// + /// 字典主键。 + /// 是否存在字典。 + public bool HasRawString(string key) + { + if (string.IsNullOrEmpty(key)) + { + throw new GameFrameworkException("Key is invalid."); + } + + return m_Dictionary.ContainsKey(key); + } + + /// + /// 根据字典主键获取字典值。 + /// + /// 字典主键。 + /// 字典值。 + public string GetRawString(string key) + { + if (string.IsNullOrEmpty(key)) + { + throw new GameFrameworkException("Key is invalid."); + } + + string value = null; + if (m_Dictionary.TryGetValue(key, out value)) + { + return value; + } + + return null; + } + + /// + /// 增加字典。 + /// + /// 字典主键。 + /// 字典内容。 + /// 是否增加字典成功。 + public bool AddRawString(string key, string value) + { + if (string.IsNullOrEmpty(key)) + { + throw new GameFrameworkException("Key is invalid."); + } + + if (m_Dictionary.ContainsKey(key)) + { + return false; + } + + m_Dictionary.Add(key, value ?? string.Empty); + return true; + } + + /// + /// 移除字典。 + /// + /// 字典主键。 + /// 是否移除字典成功。 + public bool RemoveRawString(string key) + { + if (string.IsNullOrEmpty(key)) + { + throw new GameFrameworkException("Key is invalid."); + } + + return m_Dictionary.Remove(key); + } + + /// + /// 清空所有字典。 + /// + public void RemoveAllRawStrings() + { + m_Dictionary.Clear(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/LocalizationManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/LocalizationManager.cs.meta new file mode 100644 index 0000000..f8c9dd0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Localization/LocalizationManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc0554d5f84bc5e4caaa5af77561973b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network.meta new file mode 100644 index 0000000..194969a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 10db358e21ecb0341bc7907a2add9524 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/AddressFamily.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/AddressFamily.cs new file mode 100644 index 0000000..a8e79a5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/AddressFamily.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络地址类型。 + /// + public enum AddressFamily : byte + { + /// + /// 未知。 + /// + Unknown = 0, + + /// + /// IP 版本 4。 + /// + IPv4, + + /// + /// IP 版本 6。 + /// + IPv6 + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/AddressFamily.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/AddressFamily.cs.meta new file mode 100644 index 0000000..fcb6b51 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/AddressFamily.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f0086471a7a51248ae7581b2d2ee098 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannel.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannel.cs new file mode 100644 index 0000000..251614d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannel.cs @@ -0,0 +1,164 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Net; +using System.Net.Sockets; + +namespace GameFramework.Network +{ + /// + /// 网络频道接口。 + /// + public interface INetworkChannel + { + /// + /// 获取网络频道名称。 + /// + string Name + { + get; + } + + /// + /// 获取网络频道所使用的 Socket。 + /// + Socket Socket + { + get; + } + + /// + /// 获取是否已连接。 + /// + bool Connected + { + get; + } + + /// + /// 获取网络服务类型。 + /// + ServiceType ServiceType + { + get; + } + + /// + /// 获取网络地址类型。 + /// + AddressFamily AddressFamily + { + get; + } + + /// + /// 获取要发送的消息包数量。 + /// + int SendPacketCount + { + get; + } + + /// + /// 获取累计发送的消息包数量。 + /// + int SentPacketCount + { + get; + } + + /// + /// 获取已接收未处理的消息包数量。 + /// + int ReceivePacketCount + { + get; + } + + /// + /// 获取累计已接收的消息包数量。 + /// + int ReceivedPacketCount + { + get; + } + + /// + /// 获取或设置当收到消息包时是否重置心跳流逝时间。 + /// + bool ResetHeartBeatElapseSecondsWhenReceivePacket + { + get; + set; + } + + /// + /// 获取丢失心跳的次数。 + /// + int MissHeartBeatCount + { + get; + } + + /// + /// 获取或设置心跳间隔时长,以秒为单位。 + /// + float HeartBeatInterval + { + get; + set; + } + + /// + /// 获取心跳等待时长,以秒为单位。 + /// + float HeartBeatElapseSeconds + { + get; + } + + /// + /// 注册网络消息包处理函数。 + /// + /// 要注册的网络消息包处理函数。 + void RegisterHandler(IPacketHandler handler); + + /// + /// 设置默认事件处理函数。 + /// + /// 要设置的默认事件处理函数。 + void SetDefaultHandler(EventHandler handler); + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + void Connect(IPAddress ipAddress, int port); + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + void Connect(IPAddress ipAddress, int port, object userData); + + /// + /// 关闭网络频道。 + /// + void Close(); + + /// + /// 向远程主机发送消息包。 + /// + /// 消息包类型。 + /// 要发送的消息包。 + void Send(T packet) where T : Packet; + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannel.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannel.cs.meta new file mode 100644 index 0000000..db23eb9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d615c82b424a0f841ba42857ce1ff896 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannelHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannelHelper.cs new file mode 100644 index 0000000..241f0de --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannelHelper.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.IO; + +namespace GameFramework.Network +{ + /// + /// 网络频道辅助器接口。 + /// + public interface INetworkChannelHelper + { + /// + /// 获取消息包头长度。 + /// + int PacketHeaderLength + { + get; + } + + /// + /// 初始化网络频道辅助器。 + /// + /// 网络频道。 + void Initialize(INetworkChannel networkChannel); + + /// + /// 关闭并清理网络频道辅助器。 + /// + void Shutdown(); + + /// + /// 准备进行连接。 + /// + void PrepareForConnecting(); + + /// + /// 发送心跳消息包。 + /// + /// 是否发送心跳消息包成功。 + bool SendHeartBeat(); + + /// + /// 序列化消息包。 + /// + /// 消息包类型。 + /// 要序列化的消息包。 + /// 要序列化的目标流。 + /// 是否序列化成功。 + bool Serialize(T packet, Stream destination) where T : Packet; + + /// + /// 反序列化消息包头。 + /// + /// 要反序列化的来源流。 + /// 用户自定义错误数据。 + /// 反序列化后的消息包头。 + IPacketHeader DeserializePacketHeader(Stream source, out object customErrorData); + + /// + /// 反序列化消息包。 + /// + /// 消息包头。 + /// 要反序列化的来源流。 + /// 用户自定义错误数据。 + /// 反序列化后的消息包。 + Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannelHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannelHelper.cs.meta new file mode 100644 index 0000000..f1f2108 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkChannelHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97bf22cdf6563e94fb204efda40e85a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkManager.cs new file mode 100644 index 0000000..96ce74c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkManager.cs @@ -0,0 +1,93 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Network +{ + /// + /// 网络管理器接口。 + /// + public interface INetworkManager + { + /// + /// 获取网络频道数量。 + /// + int NetworkChannelCount + { + get; + } + + /// + /// 网络连接成功事件。 + /// + event EventHandler NetworkConnected; + + /// + /// 网络连接关闭事件。 + /// + event EventHandler NetworkClosed; + + /// + /// 网络心跳包丢失事件。 + /// + event EventHandler NetworkMissHeartBeat; + + /// + /// 网络错误事件。 + /// + event EventHandler NetworkError; + + /// + /// 用户自定义网络错误事件。 + /// + event EventHandler NetworkCustomError; + + /// + /// 检查是否存在网络频道。 + /// + /// 网络频道名称。 + /// 是否存在网络频道。 + bool HasNetworkChannel(string name); + + /// + /// 获取网络频道。 + /// + /// 网络频道名称。 + /// 要获取的网络频道。 + INetworkChannel GetNetworkChannel(string name); + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + INetworkChannel[] GetAllNetworkChannels(); + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + void GetAllNetworkChannels(List results); + + /// + /// 创建网络频道。 + /// + /// 网络频道名称。 + /// 网络服务类型。 + /// 网络频道辅助器。 + /// 要创建的网络频道。 + INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper); + + /// + /// 销毁网络频道。 + /// + /// 网络频道名称。 + /// 是否销毁网络频道成功。 + bool DestroyNetworkChannel(string name); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkManager.cs.meta new file mode 100644 index 0000000..7594f03 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/INetworkManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4f5ca33aebf0644b9d5cacbb6d322ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHandler.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHandler.cs new file mode 100644 index 0000000..e157ee8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHandler.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络消息包处理器接口。 + /// + public interface IPacketHandler + { + /// + /// 获取网络消息包协议编号。 + /// + int Id + { + get; + } + + /// + /// 网络消息包处理函数。 + /// + /// 网络消息包源。 + /// 网络消息包内容。 + void Handle(object sender, Packet packet); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHandler.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHandler.cs.meta new file mode 100644 index 0000000..1e90777 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da90be0be6ea5ff448a860bed0a69368 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHeader.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHeader.cs new file mode 100644 index 0000000..b77b75b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHeader.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络消息包头接口。 + /// + public interface IPacketHeader + { + /// + /// 获取网络消息包长度。 + /// + int PacketLength + { + get; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHeader.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHeader.cs.meta new file mode 100644 index 0000000..679c719 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/IPacketHeader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2622209275a293f4fa5e7a3e751347c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkClosedEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkClosedEventArgs.cs new file mode 100644 index 0000000..86d0251 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkClosedEventArgs.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络连接关闭事件。 + /// + public sealed class NetworkClosedEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化网络连接关闭事件的新实例。 + /// + public NetworkClosedEventArgs() + { + NetworkChannel = null; + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 创建网络连接关闭事件。 + /// + /// 网络频道。 + /// 创建的网络连接关闭事件。 + public static NetworkClosedEventArgs Create(INetworkChannel networkChannel) + { + NetworkClosedEventArgs networkClosedEventArgs = ReferencePool.Acquire(); + networkClosedEventArgs.NetworkChannel = networkChannel; + return networkClosedEventArgs; + } + + /// + /// 清理网络连接关闭事件。 + /// + public override void Clear() + { + NetworkChannel = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkClosedEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkClosedEventArgs.cs.meta new file mode 100644 index 0000000..3828b9c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkClosedEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d894e462cd9eae47850f1ebf70842a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkConnectedEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkConnectedEventArgs.cs new file mode 100644 index 0000000..1329d87 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkConnectedEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络连接成功事件。 + /// + public sealed class NetworkConnectedEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化网络连接成功事件的新实例。 + /// + public NetworkConnectedEventArgs() + { + NetworkChannel = null; + UserData = null; + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建网络连接成功事件。 + /// + /// 网络频道。 + /// 用户自定义数据。 + /// 创建的网络连接成功事件。 + public static NetworkConnectedEventArgs Create(INetworkChannel networkChannel, object userData) + { + NetworkConnectedEventArgs networkConnectedEventArgs = ReferencePool.Acquire(); + networkConnectedEventArgs.NetworkChannel = networkChannel; + networkConnectedEventArgs.UserData = userData; + return networkConnectedEventArgs; + } + + /// + /// 清理网络连接成功事件。 + /// + public override void Clear() + { + NetworkChannel = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkConnectedEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkConnectedEventArgs.cs.meta new file mode 100644 index 0000000..73e6a07 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkConnectedEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a4a87c1fade1a441a9cff72c0349e3b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkCustomErrorEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkCustomErrorEventArgs.cs new file mode 100644 index 0000000..4883783 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkCustomErrorEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 用户自定义网络错误事件。 + /// + public sealed class NetworkCustomErrorEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化用户自定义网络错误事件的新实例。 + /// + public NetworkCustomErrorEventArgs() + { + NetworkChannel = null; + CustomErrorData = null; + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 获取用户自定义错误数据。 + /// + public object CustomErrorData + { + get; + private set; + } + + /// + /// 创建用户自定义网络错误事件。 + /// + /// 网络频道。 + /// 用户自定义错误数据。 + /// 创建的用户自定义网络错误事件。 + public static NetworkCustomErrorEventArgs Create(INetworkChannel networkChannel, object customErrorData) + { + NetworkCustomErrorEventArgs networkCustomErrorEventArgs = ReferencePool.Acquire(); + networkCustomErrorEventArgs.NetworkChannel = networkChannel; + networkCustomErrorEventArgs.CustomErrorData = customErrorData; + return networkCustomErrorEventArgs; + } + + /// + /// 清理用户自定义网络错误事件。 + /// + public override void Clear() + { + NetworkChannel = null; + CustomErrorData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkCustomErrorEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkCustomErrorEventArgs.cs.meta new file mode 100644 index 0000000..41f124d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkCustomErrorEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7388271e006610648989d7bd7334888b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorCode.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorCode.cs new file mode 100644 index 0000000..3c7b0ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorCode.cs @@ -0,0 +1,60 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络错误码。 + /// + public enum NetworkErrorCode : byte + { + /// + /// 未知错误。 + /// + Unknown = 0, + + /// + /// 地址族错误。 + /// + AddressFamilyError, + + /// + /// Socket 错误。 + /// + SocketError, + + /// + /// 连接错误。 + /// + ConnectError, + + /// + /// 发送错误。 + /// + SendError, + + /// + /// 接收错误。 + /// + ReceiveError, + + /// + /// 序列化错误。 + /// + SerializeError, + + /// + /// 反序列化消息包头错误。 + /// + DeserializePacketHeaderError, + + /// + /// 反序列化消息包错误。 + /// + DeserializePacketError + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorCode.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorCode.cs.meta new file mode 100644 index 0000000..30e628b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22aa127b860fbf843847ecd2e78c3b7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorEventArgs.cs new file mode 100644 index 0000000..9ffb2b6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorEventArgs.cs @@ -0,0 +1,93 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Net.Sockets; + +namespace GameFramework.Network +{ + /// + /// 网络错误事件。 + /// + public sealed class NetworkErrorEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化网络错误事件的新实例。 + /// + public NetworkErrorEventArgs() + { + NetworkChannel = null; + ErrorCode = NetworkErrorCode.Unknown; + SocketErrorCode = SocketError.Success; + ErrorMessage = null; + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 获取错误码。 + /// + public NetworkErrorCode ErrorCode + { + get; + private set; + } + + /// + /// 获取 Socket 错误码。 + /// + public SocketError SocketErrorCode + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建网络错误事件。 + /// + /// 网络频道。 + /// 错误码。 + /// Socket 错误码。 + /// 错误信息。 + /// 创建的网络错误事件。 + public static NetworkErrorEventArgs Create(INetworkChannel networkChannel, NetworkErrorCode errorCode, SocketError socketErrorCode, string errorMessage) + { + NetworkErrorEventArgs networkErrorEventArgs = ReferencePool.Acquire(); + networkErrorEventArgs.NetworkChannel = networkChannel; + networkErrorEventArgs.ErrorCode = errorCode; + networkErrorEventArgs.SocketErrorCode = socketErrorCode; + networkErrorEventArgs.ErrorMessage = errorMessage; + return networkErrorEventArgs; + } + + /// + /// 清理网络错误事件。 + /// + public override void Clear() + { + NetworkChannel = null; + ErrorCode = NetworkErrorCode.Unknown; + SocketErrorCode = SocketError.Success; + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorEventArgs.cs.meta new file mode 100644 index 0000000..d6fffcb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkErrorEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1da767b6c52678744bf340fcabc74fb1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ConnectState.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ConnectState.cs new file mode 100644 index 0000000..3252f97 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ConnectState.cs @@ -0,0 +1,42 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Net.Sockets; + +namespace GameFramework.Network +{ + internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager + { + private sealed class ConnectState + { + private readonly Socket m_Socket; + private readonly object m_UserData; + + public ConnectState(Socket socket, object userData) + { + m_Socket = socket; + m_UserData = userData; + } + + public Socket Socket + { + get + { + return m_Socket; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ConnectState.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ConnectState.cs.meta new file mode 100644 index 0000000..6717be7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ConnectState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d05dbcab6c1fb8544b73bdd23ba11f87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.HeartBeatState.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.HeartBeatState.cs new file mode 100644 index 0000000..922cb4b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.HeartBeatState.cs @@ -0,0 +1,58 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager + { + private sealed class HeartBeatState + { + private float m_HeartBeatElapseSeconds; + private int m_MissHeartBeatCount; + + public HeartBeatState() + { + m_HeartBeatElapseSeconds = 0f; + m_MissHeartBeatCount = 0; + } + + public float HeartBeatElapseSeconds + { + get + { + return m_HeartBeatElapseSeconds; + } + set + { + m_HeartBeatElapseSeconds = value; + } + } + + public int MissHeartBeatCount + { + get + { + return m_MissHeartBeatCount; + } + set + { + m_MissHeartBeatCount = value; + } + } + + public void Reset(bool resetHeartBeatElapseSeconds) + { + if (resetHeartBeatElapseSeconds) + { + m_HeartBeatElapseSeconds = 0f; + } + + m_MissHeartBeatCount = 0; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.HeartBeatState.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.HeartBeatState.cs.meta new file mode 100644 index 0000000..5494e20 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.HeartBeatState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a09e9bbabba8f04d9499ec8e6d12a65 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.NetworkChannelBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.NetworkChannelBase.cs new file mode 100644 index 0000000..58cd1c0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.NetworkChannelBase.cs @@ -0,0 +1,636 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; + +namespace GameFramework.Network +{ + internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager + { + /// + /// 网络频道基类。 + /// + private abstract class NetworkChannelBase : INetworkChannel, IDisposable + { + private const float DefaultHeartBeatInterval = 30f; + + private readonly string m_Name; + protected readonly Queue m_SendPacketPool; + protected readonly EventPool m_ReceivePacketPool; + protected readonly INetworkChannelHelper m_NetworkChannelHelper; + protected AddressFamily m_AddressFamily; + protected bool m_ResetHeartBeatElapseSecondsWhenReceivePacket; + protected float m_HeartBeatInterval; + protected Socket m_Socket; + protected readonly SendState m_SendState; + protected readonly ReceiveState m_ReceiveState; + protected readonly HeartBeatState m_HeartBeatState; + protected int m_SentPacketCount; + protected int m_ReceivedPacketCount; + protected bool m_Active; + private bool m_Disposed; + + public GameFrameworkAction NetworkChannelConnected; + public GameFrameworkAction NetworkChannelClosed; + public GameFrameworkAction NetworkChannelMissHeartBeat; + public GameFrameworkAction NetworkChannelError; + public GameFrameworkAction NetworkChannelCustomError; + + /// + /// 初始化网络频道基类的新实例。 + /// + /// 网络频道名称。 + /// 网络频道辅助器。 + public NetworkChannelBase(string name, INetworkChannelHelper networkChannelHelper) + { + m_Name = name ?? string.Empty; + m_SendPacketPool = new Queue(); + m_ReceivePacketPool = new EventPool(EventPoolMode.Default); + m_NetworkChannelHelper = networkChannelHelper; + m_AddressFamily = AddressFamily.Unknown; + m_ResetHeartBeatElapseSecondsWhenReceivePacket = false; + m_HeartBeatInterval = DefaultHeartBeatInterval; + m_Socket = null; + m_SendState = new SendState(); + m_ReceiveState = new ReceiveState(); + m_HeartBeatState = new HeartBeatState(); + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + m_Active = false; + m_Disposed = false; + + NetworkChannelConnected = null; + NetworkChannelClosed = null; + NetworkChannelMissHeartBeat = null; + NetworkChannelError = null; + NetworkChannelCustomError = null; + + networkChannelHelper.Initialize(this); + } + + /// + /// 获取网络频道名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取网络频道所使用的 Socket。 + /// + public Socket Socket + { + get + { + return m_Socket; + } + } + + /// + /// 获取是否已连接。 + /// + public bool Connected + { + get + { + if (m_Socket != null) + { + return m_Socket.Connected; + } + + return false; + } + } + + /// + /// 获取网络服务类型。 + /// + public abstract ServiceType ServiceType + { + get; + } + + /// + /// 获取网络地址类型。 + /// + public AddressFamily AddressFamily + { + get + { + return m_AddressFamily; + } + } + + /// + /// 获取要发送的消息包数量。 + /// + public int SendPacketCount + { + get + { + return m_SendPacketPool.Count; + } + } + + /// + /// 获取累计发送的消息包数量。 + /// + public int SentPacketCount + { + get + { + return m_SentPacketCount; + } + } + + /// + /// 获取已接收未处理的消息包数量。 + /// + public int ReceivePacketCount + { + get + { + return m_ReceivePacketPool.EventCount; + } + } + + /// + /// 获取累计已接收的消息包数量。 + /// + public int ReceivedPacketCount + { + get + { + return m_ReceivedPacketCount; + } + } + + /// + /// 获取或设置当收到消息包时是否重置心跳流逝时间。 + /// + public bool ResetHeartBeatElapseSecondsWhenReceivePacket + { + get + { + return m_ResetHeartBeatElapseSecondsWhenReceivePacket; + } + set + { + m_ResetHeartBeatElapseSecondsWhenReceivePacket = value; + } + } + + /// + /// 获取丢失心跳的次数。 + /// + public int MissHeartBeatCount + { + get + { + return m_HeartBeatState.MissHeartBeatCount; + } + } + + /// + /// 获取或设置心跳间隔时长,以秒为单位。 + /// + public float HeartBeatInterval + { + get + { + return m_HeartBeatInterval; + } + set + { + m_HeartBeatInterval = value; + } + } + + /// + /// 获取心跳等待时长,以秒为单位。 + /// + public float HeartBeatElapseSeconds + { + get + { + return m_HeartBeatState.HeartBeatElapseSeconds; + } + } + + /// + /// 网络频道轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public virtual void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_Socket == null || !m_Active) + { + return; + } + + ProcessSend(); + ProcessReceive(); + if (m_Socket == null || !m_Active) + { + return; + } + + m_ReceivePacketPool.Update(elapseSeconds, realElapseSeconds); + + if (m_HeartBeatInterval > 0f) + { + bool sendHeartBeat = false; + int missHeartBeatCount = 0; + lock (m_HeartBeatState) + { + if (m_Socket == null || !m_Active) + { + return; + } + + m_HeartBeatState.HeartBeatElapseSeconds += realElapseSeconds; + if (m_HeartBeatState.HeartBeatElapseSeconds >= m_HeartBeatInterval) + { + sendHeartBeat = true; + missHeartBeatCount = m_HeartBeatState.MissHeartBeatCount; + m_HeartBeatState.HeartBeatElapseSeconds = 0f; + m_HeartBeatState.MissHeartBeatCount++; + } + } + + if (sendHeartBeat && m_NetworkChannelHelper.SendHeartBeat()) + { + if (missHeartBeatCount > 0 && NetworkChannelMissHeartBeat != null) + { + NetworkChannelMissHeartBeat(this, missHeartBeatCount); + } + } + } + } + + /// + /// 关闭网络频道。 + /// + public virtual void Shutdown() + { + Close(); + m_ReceivePacketPool.Shutdown(); + m_NetworkChannelHelper.Shutdown(); + } + + /// + /// 注册网络消息包处理函数。 + /// + /// 要注册的网络消息包处理函数。 + public void RegisterHandler(IPacketHandler handler) + { + if (handler == null) + { + throw new GameFrameworkException("Packet handler is invalid."); + } + + m_ReceivePacketPool.Subscribe(handler.Id, handler.Handle); + } + + /// + /// 设置默认事件处理函数。 + /// + /// 要设置的默认事件处理函数。 + public void SetDefaultHandler(EventHandler handler) + { + m_ReceivePacketPool.SetDefaultHandler(handler); + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + public void Connect(IPAddress ipAddress, int port) + { + Connect(ipAddress, port, null); + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + public virtual void Connect(IPAddress ipAddress, int port, object userData) + { + if (m_Socket != null) + { + Close(); + m_Socket = null; + } + + switch (ipAddress.AddressFamily) + { + case System.Net.Sockets.AddressFamily.InterNetwork: + m_AddressFamily = AddressFamily.IPv4; + break; + + case System.Net.Sockets.AddressFamily.InterNetworkV6: + m_AddressFamily = AddressFamily.IPv6; + break; + + default: + string errorMessage = Utility.Text.Format("Not supported address family '{0}'.", ipAddress.AddressFamily); + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.AddressFamilyError, SocketError.Success, errorMessage); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + m_SendState.Reset(); + m_ReceiveState.PrepareForPacketHeader(m_NetworkChannelHelper.PacketHeaderLength); + } + + /// + /// 关闭连接并释放所有相关资源。 + /// + public void Close() + { + lock (this) + { + if (m_Socket == null) + { + return; + } + + m_Active = false; + + try + { + m_Socket.Shutdown(SocketShutdown.Both); + } + catch + { + } + finally + { + m_Socket.Close(); + m_Socket = null; + + if (NetworkChannelClosed != null) + { + NetworkChannelClosed(this); + } + } + + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + + lock (m_SendPacketPool) + { + m_SendPacketPool.Clear(); + } + + m_ReceivePacketPool.Clear(); + + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(true); + } + } + } + + /// + /// 向远程主机发送消息包。 + /// + /// 消息包类型。 + /// 要发送的消息包。 + public void Send(T packet) where T : Packet + { + if (m_Socket == null) + { + string errorMessage = "You must connect first."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + if (!m_Active) + { + string errorMessage = "Socket is not active."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + if (packet == null) + { + string errorMessage = "Packet is invalid."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + lock (m_SendPacketPool) + { + m_SendPacketPool.Enqueue(packet); + } + } + + /// + /// 释放资源。 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 释放资源。 + /// + /// 释放资源标记。 + private void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + Close(); + m_SendState.Dispose(); + m_ReceiveState.Dispose(); + } + + m_Disposed = true; + } + + protected virtual bool ProcessSend() + { + if (m_SendState.Stream.Length > 0 || m_SendPacketPool.Count <= 0) + { + return false; + } + + while (m_SendPacketPool.Count > 0) + { + Packet packet = null; + lock (m_SendPacketPool) + { + packet = m_SendPacketPool.Dequeue(); + } + + bool serializeResult = false; + try + { + serializeResult = m_NetworkChannelHelper.Serialize(packet, m_SendState.Stream); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SerializeError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return false; + } + + throw; + } + + if (!serializeResult) + { + string errorMessage = "Serialized packet failure."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SerializeError, SocketError.Success, errorMessage); + return false; + } + + throw new GameFrameworkException(errorMessage); + } + } + + m_SendState.Stream.Position = 0L; + return true; + } + + protected virtual void ProcessReceive() + { + } + + protected virtual bool ProcessPacketHeader() + { + try + { + object customErrorData = null; + IPacketHeader packetHeader = m_NetworkChannelHelper.DeserializePacketHeader(m_ReceiveState.Stream, out customErrorData); + + if (customErrorData != null && NetworkChannelCustomError != null) + { + NetworkChannelCustomError(this, customErrorData); + } + + if (packetHeader == null) + { + string errorMessage = "Packet header is invalid."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.DeserializePacketHeaderError, SocketError.Success, errorMessage); + return false; + } + + throw new GameFrameworkException(errorMessage); + } + + m_ReceiveState.PrepareForPacket(packetHeader); + if (packetHeader.PacketLength <= 0) + { + bool processSuccess = ProcessPacket(); + m_ReceivedPacketCount++; + return processSuccess; + } + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.DeserializePacketHeaderError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return false; + } + + throw; + } + + return true; + } + + protected virtual bool ProcessPacket() + { + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(m_ResetHeartBeatElapseSecondsWhenReceivePacket); + } + + try + { + object customErrorData = null; + Packet packet = m_NetworkChannelHelper.DeserializePacket(m_ReceiveState.PacketHeader, m_ReceiveState.Stream, out customErrorData); + + if (customErrorData != null && NetworkChannelCustomError != null) + { + NetworkChannelCustomError(this, customErrorData); + } + + if (packet != null) + { + m_ReceivePacketPool.Fire(this, packet); + } + + m_ReceiveState.PrepareForPacketHeader(m_NetworkChannelHelper.PacketHeaderLength); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.DeserializePacketError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return false; + } + + throw; + } + + return true; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.NetworkChannelBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.NetworkChannelBase.cs.meta new file mode 100644 index 0000000..ab0f778 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.NetworkChannelBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 376ac86dbb44e5e4e9da8427a7326a75 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ReceiveState.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ReceiveState.cs new file mode 100644 index 0000000..231299d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ReceiveState.cs @@ -0,0 +1,98 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.IO; + +namespace GameFramework.Network +{ + internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager + { + private sealed class ReceiveState : IDisposable + { + private const int DefaultBufferLength = 1024 * 64; + private MemoryStream m_Stream; + private IPacketHeader m_PacketHeader; + private bool m_Disposed; + + public ReceiveState() + { + m_Stream = new MemoryStream(DefaultBufferLength); + m_PacketHeader = null; + m_Disposed = false; + } + + public MemoryStream Stream + { + get + { + return m_Stream; + } + } + + public IPacketHeader PacketHeader + { + get + { + return m_PacketHeader; + } + } + + public void PrepareForPacketHeader(int packetHeaderLength) + { + Reset(packetHeaderLength, null); + } + + public void PrepareForPacket(IPacketHeader packetHeader) + { + if (packetHeader == null) + { + throw new GameFrameworkException("Packet header is invalid."); + } + + Reset(packetHeader.PacketLength, packetHeader); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_Stream != null) + { + m_Stream.Dispose(); + m_Stream = null; + } + } + + m_Disposed = true; + } + + private void Reset(int targetLength, IPacketHeader packetHeader) + { + if (targetLength < 0) + { + throw new GameFrameworkException("Target length is invalid."); + } + + m_Stream.Position = 0L; + m_Stream.SetLength(targetLength); + m_PacketHeader = packetHeader; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ReceiveState.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ReceiveState.cs.meta new file mode 100644 index 0000000..60bf2ec --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.ReceiveState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14ef71f81fbf8474d88e8c15e157a478 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.SendState.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.SendState.cs new file mode 100644 index 0000000..05f84ed --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.SendState.cs @@ -0,0 +1,67 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.IO; + +namespace GameFramework.Network +{ + internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager + { + private sealed class SendState : IDisposable + { + private const int DefaultBufferLength = 1024 * 64; + private MemoryStream m_Stream; + private bool m_Disposed; + + public SendState() + { + m_Stream = new MemoryStream(DefaultBufferLength); + m_Disposed = false; + } + + public MemoryStream Stream + { + get + { + return m_Stream; + } + } + + public void Reset() + { + m_Stream.Position = 0L; + m_Stream.SetLength(0L); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_Stream != null) + { + m_Stream.Dispose(); + m_Stream = null; + } + } + + m_Disposed = true; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.SendState.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.SendState.cs.meta new file mode 100644 index 0000000..15a8bc2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.SendState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f6aa63097e24ec4ea4bb256a3174562 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpNetworkChannel.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpNetworkChannel.cs new file mode 100644 index 0000000..65d6f06 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpNetworkChannel.cs @@ -0,0 +1,290 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Net; +using System.Net.Sockets; + +namespace GameFramework.Network +{ + internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager + { + /// + /// TCP 网络频道。 + /// + private sealed class TcpNetworkChannel : NetworkChannelBase + { + private readonly AsyncCallback m_ConnectCallback; + private readonly AsyncCallback m_SendCallback; + private readonly AsyncCallback m_ReceiveCallback; + + /// + /// 初始化网络频道的新实例。 + /// + /// 网络频道名称。 + /// 网络频道辅助器。 + public TcpNetworkChannel(string name, INetworkChannelHelper networkChannelHelper) + : base(name, networkChannelHelper) + { + m_ConnectCallback = ConnectCallback; + m_SendCallback = SendCallback; + m_ReceiveCallback = ReceiveCallback; + } + + /// + /// 获取网络服务类型。 + /// + public override ServiceType ServiceType + { + get + { + return ServiceType.Tcp; + } + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + public override void Connect(IPAddress ipAddress, int port, object userData) + { + base.Connect(ipAddress, port, userData); + m_Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + if (m_Socket == null) + { + string errorMessage = "Initialize network channel failure."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SocketError, SocketError.Success, errorMessage); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + m_NetworkChannelHelper.PrepareForConnecting(); + ConnectAsync(ipAddress, port, userData); + } + + protected override bool ProcessSend() + { + if (base.ProcessSend()) + { + SendAsync(); + return true; + } + + return false; + } + + private void ConnectAsync(IPAddress ipAddress, int port, object userData) + { + try + { + m_Socket.BeginConnect(ipAddress, port, m_ConnectCallback, new ConnectState(m_Socket, userData)); + } + catch (Exception exception) + { + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void ConnectCallback(IAsyncResult ar) + { + ConnectState socketUserData = (ConnectState)ar.AsyncState; + try + { + socketUserData.Socket.EndConnect(ar); + } + catch (ObjectDisposedException) + { + return; + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + + lock (m_SendPacketPool) + { + m_SendPacketPool.Clear(); + } + + m_ReceivePacketPool.Clear(); + + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(true); + } + + if (NetworkChannelConnected != null) + { + NetworkChannelConnected(this, socketUserData.UserData); + } + + m_Active = true; + ReceiveAsync(); + } + + private void SendAsync() + { + try + { + m_Socket.BeginSend(m_SendState.Stream.GetBuffer(), (int)m_SendState.Stream.Position, (int)(m_SendState.Stream.Length - m_SendState.Stream.Position), SocketFlags.None, m_SendCallback, m_Socket); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void SendCallback(IAsyncResult ar) + { + Socket socket = (Socket)ar.AsyncState; + if (!socket.Connected) + { + return; + } + + int bytesSent = 0; + try + { + bytesSent = socket.EndSend(ar); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SendState.Stream.Position += bytesSent; + if (m_SendState.Stream.Position < m_SendState.Stream.Length) + { + SendAsync(); + return; + } + + m_SentPacketCount++; + m_SendState.Reset(); + } + + private void ReceiveAsync() + { + try + { + m_Socket.BeginReceive(m_ReceiveState.Stream.GetBuffer(), (int)m_ReceiveState.Stream.Position, (int)(m_ReceiveState.Stream.Length - m_ReceiveState.Stream.Position), SocketFlags.None, m_ReceiveCallback, m_Socket); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void ReceiveCallback(IAsyncResult ar) + { + Socket socket = (Socket)ar.AsyncState; + if (!socket.Connected) + { + return; + } + + int bytesReceived = 0; + try + { + bytesReceived = socket.EndReceive(ar); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + if (bytesReceived <= 0) + { + Close(); + return; + } + + m_ReceiveState.Stream.Position += bytesReceived; + if (m_ReceiveState.Stream.Position < m_ReceiveState.Stream.Length) + { + ReceiveAsync(); + return; + } + + m_ReceiveState.Stream.Position = 0L; + + bool processSuccess = false; + if (m_ReceiveState.PacketHeader != null) + { + processSuccess = ProcessPacket(); + m_ReceivedPacketCount++; + } + else + { + processSuccess = ProcessPacketHeader(); + } + + if (processSuccess) + { + ReceiveAsync(); + return; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpNetworkChannel.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpNetworkChannel.cs.meta new file mode 100644 index 0000000..5ede615 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpNetworkChannel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3cb93e6d4e800748b05863cfb195203 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs new file mode 100644 index 0000000..6afe5ca --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs @@ -0,0 +1,266 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Net; +using System.Net.Sockets; + +namespace GameFramework.Network +{ + internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager + { + /// + /// 使用同步接收的 TCP 网络频道。 + /// + private sealed class TcpWithSyncReceiveNetworkChannel : NetworkChannelBase + { + private readonly AsyncCallback m_ConnectCallback; + private readonly AsyncCallback m_SendCallback; + + /// + /// 初始化网络频道的新实例。 + /// + /// 网络频道名称。 + /// 网络频道辅助器。 + public TcpWithSyncReceiveNetworkChannel(string name, INetworkChannelHelper networkChannelHelper) + : base(name, networkChannelHelper) + { + m_ConnectCallback = ConnectCallback; + m_SendCallback = SendCallback; + } + + /// + /// 获取网络服务类型。 + /// + public override ServiceType ServiceType + { + get + { + return ServiceType.TcpWithSyncReceive; + } + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + public override void Connect(IPAddress ipAddress, int port, object userData) + { + base.Connect(ipAddress, port, userData); + m_Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + if (m_Socket == null) + { + string errorMessage = "Initialize network channel failure."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SocketError, SocketError.Success, errorMessage); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + m_NetworkChannelHelper.PrepareForConnecting(); + ConnectAsync(ipAddress, port, userData); + } + + protected override bool ProcessSend() + { + if (base.ProcessSend()) + { + SendAsync(); + return true; + } + + return false; + } + + protected override void ProcessReceive() + { + base.ProcessReceive(); + while (m_Socket.Available > 0) + { + if (!ReceiveSync()) + { + break; + } + } + } + + private void ConnectAsync(IPAddress ipAddress, int port, object userData) + { + try + { + m_Socket.BeginConnect(ipAddress, port, m_ConnectCallback, new ConnectState(m_Socket, userData)); + } + catch (Exception exception) + { + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void ConnectCallback(IAsyncResult ar) + { + ConnectState socketUserData = (ConnectState)ar.AsyncState; + try + { + socketUserData.Socket.EndConnect(ar); + } + catch (ObjectDisposedException) + { + return; + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + + lock (m_SendPacketPool) + { + m_SendPacketPool.Clear(); + } + + m_ReceivePacketPool.Clear(); + + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(true); + } + + if (NetworkChannelConnected != null) + { + NetworkChannelConnected(this, socketUserData.UserData); + } + + m_Active = true; + } + + private void SendAsync() + { + try + { + m_Socket.BeginSend(m_SendState.Stream.GetBuffer(), (int)m_SendState.Stream.Position, (int)(m_SendState.Stream.Length - m_SendState.Stream.Position), SocketFlags.None, m_SendCallback, m_Socket); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void SendCallback(IAsyncResult ar) + { + Socket socket = (Socket)ar.AsyncState; + if (!socket.Connected) + { + return; + } + + int bytesSent = 0; + try + { + bytesSent = socket.EndSend(ar); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SendState.Stream.Position += bytesSent; + if (m_SendState.Stream.Position < m_SendState.Stream.Length) + { + SendAsync(); + return; + } + + m_SentPacketCount++; + m_SendState.Reset(); + } + + private bool ReceiveSync() + { + try + { + int bytesReceived = m_Socket.Receive(m_ReceiveState.Stream.GetBuffer(), (int)m_ReceiveState.Stream.Position, (int)(m_ReceiveState.Stream.Length - m_ReceiveState.Stream.Position), SocketFlags.None); + if (bytesReceived <= 0) + { + Close(); + return false; + } + + m_ReceiveState.Stream.Position += bytesReceived; + if (m_ReceiveState.Stream.Position < m_ReceiveState.Stream.Length) + { + return false; + } + + m_ReceiveState.Stream.Position = 0L; + + bool processSuccess = false; + if (m_ReceiveState.PacketHeader != null) + { + processSuccess = ProcessPacket(); + m_ReceivedPacketCount++; + } + else + { + processSuccess = ProcessPacketHeader(); + } + + return processSuccess; + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return false; + } + + throw; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs.meta new file mode 100644 index 0000000..0f2e3a2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d44da6da8c3fe4f4c90e27436059e3fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.cs new file mode 100644 index 0000000..5ad7562 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.cs @@ -0,0 +1,353 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Net.Sockets; + +namespace GameFramework.Network +{ + /// + /// 网络管理器。 + /// + internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager + { + private readonly Dictionary m_NetworkChannels; + + private EventHandler m_NetworkConnectedEventHandler; + private EventHandler m_NetworkClosedEventHandler; + private EventHandler m_NetworkMissHeartBeatEventHandler; + private EventHandler m_NetworkErrorEventHandler; + private EventHandler m_NetworkCustomErrorEventHandler; + + /// + /// 初始化网络管理器的新实例。 + /// + public NetworkManager() + { + m_NetworkChannels = new Dictionary(StringComparer.Ordinal); + m_NetworkConnectedEventHandler = null; + m_NetworkClosedEventHandler = null; + m_NetworkMissHeartBeatEventHandler = null; + m_NetworkErrorEventHandler = null; + m_NetworkCustomErrorEventHandler = null; + } + + /// + /// 获取网络频道数量。 + /// + public int NetworkChannelCount + { + get + { + return m_NetworkChannels.Count; + } + } + + /// + /// 网络连接成功事件。 + /// + public event EventHandler NetworkConnected + { + add + { + m_NetworkConnectedEventHandler += value; + } + remove + { + m_NetworkConnectedEventHandler -= value; + } + } + + /// + /// 网络连接关闭事件。 + /// + public event EventHandler NetworkClosed + { + add + { + m_NetworkClosedEventHandler += value; + } + remove + { + m_NetworkClosedEventHandler -= value; + } + } + + /// + /// 网络心跳包丢失事件。 + /// + public event EventHandler NetworkMissHeartBeat + { + add + { + m_NetworkMissHeartBeatEventHandler += value; + } + remove + { + m_NetworkMissHeartBeatEventHandler -= value; + } + } + + /// + /// 网络错误事件。 + /// + public event EventHandler NetworkError + { + add + { + m_NetworkErrorEventHandler += value; + } + remove + { + m_NetworkErrorEventHandler -= value; + } + } + + /// + /// 用户自定义网络错误事件。 + /// + public event EventHandler NetworkCustomError + { + add + { + m_NetworkCustomErrorEventHandler += value; + } + remove + { + m_NetworkCustomErrorEventHandler -= value; + } + } + + /// + /// 网络管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + foreach (KeyValuePair networkChannel in m_NetworkChannels) + { + networkChannel.Value.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理网络管理器。 + /// + internal override void Shutdown() + { + foreach (KeyValuePair networkChannel in m_NetworkChannels) + { + NetworkChannelBase networkChannelBase = networkChannel.Value; + networkChannelBase.NetworkChannelConnected -= OnNetworkChannelConnected; + networkChannelBase.NetworkChannelClosed -= OnNetworkChannelClosed; + networkChannelBase.NetworkChannelMissHeartBeat -= OnNetworkChannelMissHeartBeat; + networkChannelBase.NetworkChannelError -= OnNetworkChannelError; + networkChannelBase.NetworkChannelCustomError -= OnNetworkChannelCustomError; + networkChannelBase.Shutdown(); + } + + m_NetworkChannels.Clear(); + } + + /// + /// 检查是否存在网络频道。 + /// + /// 网络频道名称。 + /// 是否存在网络频道。 + public bool HasNetworkChannel(string name) + { + return m_NetworkChannels.ContainsKey(name ?? string.Empty); + } + + /// + /// 获取网络频道。 + /// + /// 网络频道名称。 + /// 要获取的网络频道。 + public INetworkChannel GetNetworkChannel(string name) + { + NetworkChannelBase networkChannel = null; + if (m_NetworkChannels.TryGetValue(name ?? string.Empty, out networkChannel)) + { + return networkChannel; + } + + return null; + } + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + public INetworkChannel[] GetAllNetworkChannels() + { + int index = 0; + INetworkChannel[] results = new INetworkChannel[m_NetworkChannels.Count]; + foreach (KeyValuePair networkChannel in m_NetworkChannels) + { + results[index++] = networkChannel.Value; + } + + return results; + } + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + public void GetAllNetworkChannels(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair networkChannel in m_NetworkChannels) + { + results.Add(networkChannel.Value); + } + } + + /// + /// 创建网络频道。 + /// + /// 网络频道名称。 + /// 网络服务类型。 + /// 网络频道辅助器。 + /// 要创建的网络频道。 + public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper) + { + if (networkChannelHelper == null) + { + throw new GameFrameworkException("Network channel helper is invalid."); + } + + if (networkChannelHelper.PacketHeaderLength < 0) + { + throw new GameFrameworkException("Packet header length is invalid."); + } + + if (HasNetworkChannel(name)) + { + throw new GameFrameworkException(Utility.Text.Format("Already exist network channel '{0}'.", name ?? string.Empty)); + } + + NetworkChannelBase networkChannel = null; + switch (serviceType) + { + case ServiceType.Tcp: + networkChannel = new TcpNetworkChannel(name, networkChannelHelper); + break; + + case ServiceType.TcpWithSyncReceive: + networkChannel = new TcpWithSyncReceiveNetworkChannel(name, networkChannelHelper); + break; + + default: + throw new GameFrameworkException(Utility.Text.Format("Not supported service type '{0}'.", serviceType)); + } + + networkChannel.NetworkChannelConnected += OnNetworkChannelConnected; + networkChannel.NetworkChannelClosed += OnNetworkChannelClosed; + networkChannel.NetworkChannelMissHeartBeat += OnNetworkChannelMissHeartBeat; + networkChannel.NetworkChannelError += OnNetworkChannelError; + networkChannel.NetworkChannelCustomError += OnNetworkChannelCustomError; + m_NetworkChannels.Add(name, networkChannel); + return networkChannel; + } + + /// + /// 销毁网络频道。 + /// + /// 网络频道名称。 + /// 是否销毁网络频道成功。 + public bool DestroyNetworkChannel(string name) + { + NetworkChannelBase networkChannel = null; + if (m_NetworkChannels.TryGetValue(name ?? string.Empty, out networkChannel)) + { + networkChannel.NetworkChannelConnected -= OnNetworkChannelConnected; + networkChannel.NetworkChannelClosed -= OnNetworkChannelClosed; + networkChannel.NetworkChannelMissHeartBeat -= OnNetworkChannelMissHeartBeat; + networkChannel.NetworkChannelError -= OnNetworkChannelError; + networkChannel.NetworkChannelCustomError -= OnNetworkChannelCustomError; + networkChannel.Shutdown(); + return m_NetworkChannels.Remove(name); + } + + return false; + } + + private void OnNetworkChannelConnected(NetworkChannelBase networkChannel, object userData) + { + if (m_NetworkConnectedEventHandler != null) + { + lock (m_NetworkConnectedEventHandler) + { + NetworkConnectedEventArgs networkConnectedEventArgs = NetworkConnectedEventArgs.Create(networkChannel, userData); + m_NetworkConnectedEventHandler(this, networkConnectedEventArgs); + ReferencePool.Release(networkConnectedEventArgs); + } + } + } + + private void OnNetworkChannelClosed(NetworkChannelBase networkChannel) + { + if (m_NetworkClosedEventHandler != null) + { + lock (m_NetworkClosedEventHandler) + { + NetworkClosedEventArgs networkClosedEventArgs = NetworkClosedEventArgs.Create(networkChannel); + m_NetworkClosedEventHandler(this, networkClosedEventArgs); + ReferencePool.Release(networkClosedEventArgs); + } + } + } + + private void OnNetworkChannelMissHeartBeat(NetworkChannelBase networkChannel, int missHeartBeatCount) + { + if (m_NetworkMissHeartBeatEventHandler != null) + { + lock (m_NetworkMissHeartBeatEventHandler) + { + NetworkMissHeartBeatEventArgs networkMissHeartBeatEventArgs = NetworkMissHeartBeatEventArgs.Create(networkChannel, missHeartBeatCount); + m_NetworkMissHeartBeatEventHandler(this, networkMissHeartBeatEventArgs); + ReferencePool.Release(networkMissHeartBeatEventArgs); + } + } + } + + private void OnNetworkChannelError(NetworkChannelBase networkChannel, NetworkErrorCode errorCode, SocketError socketErrorCode, string errorMessage) + { + if (m_NetworkErrorEventHandler != null) + { + lock (m_NetworkErrorEventHandler) + { + NetworkErrorEventArgs networkErrorEventArgs = NetworkErrorEventArgs.Create(networkChannel, errorCode, socketErrorCode, errorMessage); + m_NetworkErrorEventHandler(this, networkErrorEventArgs); + ReferencePool.Release(networkErrorEventArgs); + } + } + } + + private void OnNetworkChannelCustomError(NetworkChannelBase networkChannel, object customErrorData) + { + if (m_NetworkCustomErrorEventHandler != null) + { + lock (m_NetworkCustomErrorEventHandler) + { + NetworkCustomErrorEventArgs networkCustomErrorEventArgs = NetworkCustomErrorEventArgs.Create(networkChannel, customErrorData); + m_NetworkCustomErrorEventHandler(this, networkCustomErrorEventArgs); + ReferencePool.Release(networkCustomErrorEventArgs); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.cs.meta new file mode 100644 index 0000000..b8ee58e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 236059f35ec1d9e4db5b2b163e94a203 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkMissHeartBeatEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkMissHeartBeatEventArgs.cs new file mode 100644 index 0000000..1554709 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkMissHeartBeatEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络心跳包丢失事件。 + /// + public sealed class NetworkMissHeartBeatEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化网络心跳包丢失事件的新实例。 + /// + public NetworkMissHeartBeatEventArgs() + { + NetworkChannel = null; + MissCount = 0; + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 获取心跳包已丢失次数。 + /// + public int MissCount + { + get; + private set; + } + + /// + /// 创建网络心跳包丢失事件。 + /// + /// 网络频道。 + /// 心跳包已丢失次数。 + /// 创建的网络心跳包丢失事件。 + public static NetworkMissHeartBeatEventArgs Create(INetworkChannel networkChannel, int missCount) + { + NetworkMissHeartBeatEventArgs networkMissHeartBeatEventArgs = ReferencePool.Acquire(); + networkMissHeartBeatEventArgs.NetworkChannel = networkChannel; + networkMissHeartBeatEventArgs.MissCount = missCount; + return networkMissHeartBeatEventArgs; + } + + /// + /// 清理网络心跳包丢失事件。 + /// + public override void Clear() + { + NetworkChannel = null; + MissCount = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkMissHeartBeatEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkMissHeartBeatEventArgs.cs.meta new file mode 100644 index 0000000..bc548f7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/NetworkMissHeartBeatEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ddaae9937a6f8943abbc13dc6893472 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/Packet.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/Packet.cs new file mode 100644 index 0000000..bf3904e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/Packet.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络消息包基类。 + /// + public abstract class Packet : BaseEventArgs + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/Packet.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/Packet.cs.meta new file mode 100644 index 0000000..e1e9f55 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/Packet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb5da4bb10dc80c4a9f9fb025ea3a1c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/ServiceType.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/ServiceType.cs new file mode 100644 index 0000000..691cb64 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/ServiceType.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Network +{ + /// + /// 网络服务类型。 + /// + public enum ServiceType : byte + { + /// + /// TCP 网络服务。 + /// + Tcp = 0, + + /// + /// 使用同步接收的 TCP 网络服务。 + /// + TcpWithSyncReceive + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/ServiceType.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/ServiceType.cs.meta new file mode 100644 index 0000000..f5411a8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Network/ServiceType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 589497222629cc3478a8126164285750 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool.meta new file mode 100644 index 0000000..a4c3fa2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fce8ee9a896d4e944b00c72652ce67e6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPool.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPool.cs new file mode 100644 index 0000000..b24da05 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPool.cs @@ -0,0 +1,218 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.ObjectPool +{ + /// + /// 对象池接口。 + /// + /// 对象类型。 + public interface IObjectPool where T : ObjectBase + { + /// + /// 获取对象池名称。 + /// + string Name + { + get; + } + + /// + /// 获取对象池完整名称。 + /// + string FullName + { + get; + } + + /// + /// 获取对象池对象类型。 + /// + Type ObjectType + { + get; + } + + /// + /// 获取对象池中对象的数量。 + /// + int Count + { + get; + } + + /// + /// 获取对象池中能被释放的对象的数量。 + /// + int CanReleaseCount + { + get; + } + + /// + /// 获取是否允许对象被多次获取。 + /// + bool AllowMultiSpawn + { + get; + } + + /// + /// 获取或设置对象池自动释放可释放对象的间隔秒数。 + /// + float AutoReleaseInterval + { + get; + set; + } + + /// + /// 获取或设置对象池的容量。 + /// + int Capacity + { + get; + set; + } + + /// + /// 获取或设置对象池对象过期秒数。 + /// + float ExpireTime + { + get; + set; + } + + /// + /// 获取或设置对象池的优先级。 + /// + int Priority + { + get; + set; + } + + /// + /// 创建对象。 + /// + /// 对象。 + /// 对象是否已被获取。 + void Register(T obj, bool spawned); + + /// + /// 检查对象。 + /// + /// 要检查的对象是否存在。 + bool CanSpawn(); + + /// + /// 检查对象。 + /// + /// 对象名称。 + /// 要检查的对象是否存在。 + bool CanSpawn(string name); + + /// + /// 获取对象。 + /// + /// 要获取的对象。 + T Spawn(); + + /// + /// 获取对象。 + /// + /// 对象名称。 + /// 要获取的对象。 + T Spawn(string name); + + /// + /// 回收对象。 + /// + /// 要回收的对象。 + void Unspawn(T obj); + + /// + /// 回收对象。 + /// + /// 要回收的对象。 + void Unspawn(object target); + + /// + /// 设置对象是否被加锁。 + /// + /// 要设置被加锁的对象。 + /// 是否被加锁。 + void SetLocked(T obj, bool locked); + + /// + /// 设置对象是否被加锁。 + /// + /// 要设置被加锁的对象。 + /// 是否被加锁。 + void SetLocked(object target, bool locked); + + /// + /// 设置对象的优先级。 + /// + /// 要设置优先级的对象。 + /// 优先级。 + void SetPriority(T obj, int priority); + + /// + /// 设置对象的优先级。 + /// + /// 要设置优先级的对象。 + /// 优先级。 + void SetPriority(object target, int priority); + + /// + /// 释放对象。 + /// + /// 要释放的对象。 + /// 释放对象是否成功。 + bool ReleaseObject(T obj); + + /// + /// 释放对象。 + /// + /// 要释放的对象。 + /// 释放对象是否成功。 + bool ReleaseObject(object target); + + /// + /// 释放对象池中的可释放对象。 + /// + void Release(); + + /// + /// 释放对象池中的可释放对象。 + /// + /// 尝试释放对象数量。 + void Release(int toReleaseCount); + + /// + /// 释放对象池中的可释放对象。 + /// + /// 释放对象筛选函数。 + void Release(ReleaseObjectFilterCallback releaseObjectFilterCallback); + + /// + /// 释放对象池中的可释放对象。 + /// + /// 尝试释放对象数量。 + /// 释放对象筛选函数。 + void Release(int toReleaseCount, ReleaseObjectFilterCallback releaseObjectFilterCallback); + + /// + /// 释放对象池中的所有未使用对象。 + /// + void ReleaseAllUnused(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPool.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPool.cs.meta new file mode 100644 index 0000000..2c42f7a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d7f4534c9efc814bbebec8e658429f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPoolManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPoolManager.cs new file mode 100644 index 0000000..3b9477c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPoolManager.cs @@ -0,0 +1,751 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.ObjectPool +{ + /// + /// 对象池管理器。 + /// + public interface IObjectPoolManager + { + /// + /// 获取对象池数量。 + /// + int Count + { + get; + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 是否存在对象池。 + bool HasObjectPool() where T : ObjectBase; + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 是否存在对象池。 + bool HasObjectPool(Type objectType); + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 是否存在对象池。 + bool HasObjectPool(string name) where T : ObjectBase; + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 是否存在对象池。 + bool HasObjectPool(Type objectType, string name); + + /// + /// 检查是否存在对象池。 + /// + /// 要检查的条件。 + /// 是否存在对象池。 + bool HasObjectPool(Predicate condition); + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 要获取的对象池。 + IObjectPool GetObjectPool() where T : ObjectBase; + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 要获取的对象池。 + ObjectPoolBase GetObjectPool(Type objectType); + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要获取的对象池。 + IObjectPool GetObjectPool(string name) where T : ObjectBase; + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要获取的对象池。 + ObjectPoolBase GetObjectPool(Type objectType, string name); + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + ObjectPoolBase GetObjectPool(Predicate condition); + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + ObjectPoolBase[] GetObjectPools(Predicate condition); + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + void GetObjectPools(Predicate condition, List results); + + /// + /// 获取所有对象池。 + /// + /// 所有对象池。 + ObjectPoolBase[] GetAllObjectPools(); + + /// + /// 获取所有对象池。 + /// + /// 所有对象池。 + void GetAllObjectPools(List results); + + /// + /// 获取所有对象池。 + /// + /// 是否根据对象池的优先级排序。 + /// 所有对象池。 + ObjectPoolBase[] GetAllObjectPools(bool sort); + + /// + /// 获取所有对象池。 + /// + /// 是否根据对象池的优先级排序。 + /// 所有对象池。 + void GetAllObjectPools(bool sort, List results); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool() where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(string name) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(int capacity) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(float expireTime) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(string name, int capacity) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(string name, float expireTime) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(int capacity, float expireTime) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(int capacity, int priority) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, int priority); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime, int priority); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, float expireTime) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, int priority) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, int priority); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(string name, float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime, int priority); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(int capacity, float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority); + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + IObjectPool CreateSingleSpawnObjectPool(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool() where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(string name) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(int capacity) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(float expireTime) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(string name, int capacity) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(string name, float expireTime) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(int capacity, float expireTime) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(int capacity, int priority) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, int priority); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime, int priority); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, float expireTime) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, int priority) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, int priority); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(string name, float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime, int priority); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(int capacity, float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority); + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + IObjectPool CreateMultiSpawnObjectPool(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase; + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority); + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 是否销毁对象池成功。 + bool DestroyObjectPool() where T : ObjectBase; + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 是否销毁对象池成功。 + bool DestroyObjectPool(Type objectType); + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池名称。 + /// 是否销毁对象池成功。 + bool DestroyObjectPool(string name) where T : ObjectBase; + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池名称。 + /// 是否销毁对象池成功。 + bool DestroyObjectPool(Type objectType, string name); + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池。 + /// 是否销毁对象池成功。 + bool DestroyObjectPool(IObjectPool objectPool) where T : ObjectBase; + + /// + /// 销毁对象池。 + /// + /// 要销毁的对象池。 + /// 是否销毁对象池成功。 + bool DestroyObjectPool(ObjectPoolBase objectPool); + + /// + /// 释放对象池中的可释放对象。 + /// + void Release(); + + /// + /// 释放对象池中的所有未使用对象。 + /// + void ReleaseAllUnused(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPoolManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPoolManager.cs.meta new file mode 100644 index 0000000..42691f2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/IObjectPoolManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef5c4eae53bb52e42a90d1c942b95714 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectBase.cs new file mode 100644 index 0000000..b7d3a78 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectBase.cs @@ -0,0 +1,207 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.ObjectPool +{ + /// + /// 对象基类。 + /// + public abstract class ObjectBase : IReference + { + private string m_Name; + private object m_Target; + private bool m_Locked; + private int m_Priority; + private DateTime m_LastUseTime; + + /// + /// 初始化对象基类的新实例。 + /// + public ObjectBase() + { + m_Name = null; + m_Target = null; + m_Locked = false; + m_Priority = 0; + m_LastUseTime = default(DateTime); + } + + /// + /// 获取对象名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取对象。 + /// + public object Target + { + get + { + return m_Target; + } + } + + /// + /// 获取或设置对象是否被加锁。 + /// + public bool Locked + { + get + { + return m_Locked; + } + set + { + m_Locked = value; + } + } + + /// + /// 获取或设置对象的优先级。 + /// + public int Priority + { + get + { + return m_Priority; + } + set + { + m_Priority = value; + } + } + + /// + /// 获取自定义释放检查标记。 + /// + public virtual bool CustomCanReleaseFlag + { + get + { + return true; + } + } + + /// + /// 获取对象上次使用时间。 + /// + public DateTime LastUseTime + { + get + { + return m_LastUseTime; + } + internal set + { + m_LastUseTime = value; + } + } + + /// + /// 初始化对象基类。 + /// + /// 对象。 + protected void Initialize(object target) + { + Initialize(null, target, false, 0); + } + + /// + /// 初始化对象基类。 + /// + /// 对象名称。 + /// 对象。 + protected void Initialize(string name, object target) + { + Initialize(name, target, false, 0); + } + + /// + /// 初始化对象基类。 + /// + /// 对象名称。 + /// 对象。 + /// 对象是否被加锁。 + protected void Initialize(string name, object target, bool locked) + { + Initialize(name, target, locked, 0); + } + + /// + /// 初始化对象基类。 + /// + /// 对象名称。 + /// 对象。 + /// 对象的优先级。 + protected void Initialize(string name, object target, int priority) + { + Initialize(name, target, false, priority); + } + + /// + /// 初始化对象基类。 + /// + /// 对象名称。 + /// 对象。 + /// 对象是否被加锁。 + /// 对象的优先级。 + protected void Initialize(string name, object target, bool locked, int priority) + { + if (target == null) + { + throw new GameFrameworkException(Utility.Text.Format("Target '{0}' is invalid.", name)); + } + + m_Name = name ?? string.Empty; + m_Target = target; + m_Locked = locked; + m_Priority = priority; + m_LastUseTime = DateTime.UtcNow; + } + + /// + /// 清理对象基类。 + /// + public virtual void Clear() + { + m_Name = null; + m_Target = null; + m_Locked = false; + m_Priority = 0; + m_LastUseTime = default(DateTime); + } + + /// + /// 获取对象时的事件。 + /// + protected internal virtual void OnSpawn() + { + } + + /// + /// 回收对象时的事件。 + /// + protected internal virtual void OnUnspawn() + { + } + + /// + /// 释放对象。 + /// + /// 是否是关闭对象池时触发。 + protected internal abstract void Release(bool isShutdown); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectBase.cs.meta new file mode 100644 index 0000000..01b6c8a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ef716dcc078cbf4cbe1a2b3bf2fc584 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectInfo.cs new file mode 100644 index 0000000..e2105cf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectInfo.cs @@ -0,0 +1,122 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Runtime.InteropServices; + +namespace GameFramework.ObjectPool +{ + /// + /// 对象信息。 + /// + [StructLayout(LayoutKind.Auto)] + public struct ObjectInfo + { + private readonly string m_Name; + private readonly bool m_Locked; + private readonly bool m_CustomCanReleaseFlag; + private readonly int m_Priority; + private readonly DateTime m_LastUseTime; + private readonly int m_SpawnCount; + + /// + /// 初始化对象信息的新实例。 + /// + /// 对象名称。 + /// 对象是否被加锁。 + /// 对象自定义释放检查标记。 + /// 对象的优先级。 + /// 对象上次使用时间。 + /// 对象的获取计数。 + public ObjectInfo(string name, bool locked, bool customCanReleaseFlag, int priority, DateTime lastUseTime, int spawnCount) + { + m_Name = name; + m_Locked = locked; + m_CustomCanReleaseFlag = customCanReleaseFlag; + m_Priority = priority; + m_LastUseTime = lastUseTime; + m_SpawnCount = spawnCount; + } + + /// + /// 获取对象名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取对象是否被加锁。 + /// + public bool Locked + { + get + { + return m_Locked; + } + } + + /// + /// 获取对象自定义释放检查标记。 + /// + public bool CustomCanReleaseFlag + { + get + { + return m_CustomCanReleaseFlag; + } + } + + /// + /// 获取对象的优先级。 + /// + public int Priority + { + get + { + return m_Priority; + } + } + + /// + /// 获取对象上次使用时间。 + /// + public DateTime LastUseTime + { + get + { + return m_LastUseTime; + } + } + + /// + /// 获取对象是否正在使用。 + /// + public bool IsInUse + { + get + { + return m_SpawnCount > 0; + } + } + + /// + /// 获取对象的获取计数。 + /// + public int SpawnCount + { + get + { + return m_SpawnCount; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectInfo.cs.meta new file mode 100644 index 0000000..cbb6c9e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2841a08993aedf46aa28f1a1c219585 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolBase.cs new file mode 100644 index 0000000..d70b6fa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolBase.cs @@ -0,0 +1,152 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.ObjectPool +{ + /// + /// 对象池基类。 + /// + public abstract class ObjectPoolBase + { + private readonly string m_Name; + + /// + /// 初始化对象池基类的新实例。 + /// + public ObjectPoolBase() + : this(null) + { + } + + /// + /// 初始化对象池基类的新实例。 + /// + /// 对象池名称。 + public ObjectPoolBase(string name) + { + m_Name = name ?? string.Empty; + } + + /// + /// 获取对象池名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取对象池完整名称。 + /// + public string FullName + { + get + { + return new TypeNamePair(ObjectType, m_Name).ToString(); + } + } + + /// + /// 获取对象池对象类型。 + /// + public abstract Type ObjectType + { + get; + } + + /// + /// 获取对象池中对象的数量。 + /// + public abstract int Count + { + get; + } + + /// + /// 获取对象池中能被释放的对象的数量。 + /// + public abstract int CanReleaseCount + { + get; + } + + /// + /// 获取是否允许对象被多次获取。 + /// + public abstract bool AllowMultiSpawn + { + get; + } + + /// + /// 获取或设置对象池自动释放可释放对象的间隔秒数。 + /// + public abstract float AutoReleaseInterval + { + get; + set; + } + + /// + /// 获取或设置对象池的容量。 + /// + public abstract int Capacity + { + get; + set; + } + + /// + /// 获取或设置对象池对象过期秒数。 + /// + public abstract float ExpireTime + { + get; + set; + } + + /// + /// 获取或设置对象池的优先级。 + /// + public abstract int Priority + { + get; + set; + } + + /// + /// 释放对象池中的可释放对象。 + /// + public abstract void Release(); + + /// + /// 释放对象池中的可释放对象。 + /// + /// 尝试释放对象数量。 + public abstract void Release(int toReleaseCount); + + /// + /// 释放对象池中的所有未使用对象。 + /// + public abstract void ReleaseAllUnused(); + + /// + /// 获取所有对象信息。 + /// + /// 所有对象信息。 + public abstract ObjectInfo[] GetAllObjectInfos(); + + internal abstract void Update(float elapseSeconds, float realElapseSeconds); + + internal abstract void Shutdown(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolBase.cs.meta new file mode 100644 index 0000000..b0af2f1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb3ff0b617109874fbc72b070d8a3c68 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.Object.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.Object.cs new file mode 100644 index 0000000..e20d765 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.Object.cs @@ -0,0 +1,196 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.ObjectPool +{ + internal sealed partial class ObjectPoolManager : GameFrameworkModule, IObjectPoolManager + { + /// + /// 内部对象。 + /// + /// 对象类型。 + private sealed class Object : IReference where T : ObjectBase + { + private T m_Object; + private int m_SpawnCount; + + /// + /// 初始化内部对象的新实例。 + /// + public Object() + { + m_Object = null; + m_SpawnCount = 0; + } + + /// + /// 获取对象名称。 + /// + public string Name + { + get + { + return m_Object.Name; + } + } + + /// + /// 获取对象是否被加锁。 + /// + public bool Locked + { + get + { + return m_Object.Locked; + } + internal set + { + m_Object.Locked = value; + } + } + + /// + /// 获取对象的优先级。 + /// + public int Priority + { + get + { + return m_Object.Priority; + } + internal set + { + m_Object.Priority = value; + } + } + + /// + /// 获取自定义释放检查标记。 + /// + public bool CustomCanReleaseFlag + { + get + { + return m_Object.CustomCanReleaseFlag; + } + } + + /// + /// 获取对象上次使用时间。 + /// + public DateTime LastUseTime + { + get + { + return m_Object.LastUseTime; + } + } + + /// + /// 获取对象是否正在使用。 + /// + public bool IsInUse + { + get + { + return m_SpawnCount > 0; + } + } + + /// + /// 获取对象的获取计数。 + /// + public int SpawnCount + { + get + { + return m_SpawnCount; + } + } + + /// + /// 创建内部对象。 + /// + /// 对象。 + /// 对象是否已被获取。 + /// 创建的内部对象。 + public static Object Create(T obj, bool spawned) + { + if (obj == null) + { + throw new GameFrameworkException("Object is invalid."); + } + + Object internalObject = ReferencePool.Acquire>(); + internalObject.m_Object = obj; + internalObject.m_SpawnCount = spawned ? 1 : 0; + if (spawned) + { + obj.OnSpawn(); + } + + return internalObject; + } + + /// + /// 清理内部对象。 + /// + public void Clear() + { + m_Object = null; + m_SpawnCount = 0; + } + + /// + /// 查看对象。 + /// + /// 对象。 + public T Peek() + { + return m_Object; + } + + /// + /// 获取对象。 + /// + /// 对象。 + public T Spawn() + { + m_SpawnCount++; + m_Object.LastUseTime = DateTime.UtcNow; + m_Object.OnSpawn(); + return m_Object; + } + + /// + /// 回收对象。 + /// + public void Unspawn() + { + m_Object.OnUnspawn(); + m_Object.LastUseTime = DateTime.UtcNow; + m_SpawnCount--; + if (m_SpawnCount < 0) + { + throw new GameFrameworkException(Utility.Text.Format("Object '{0}' spawn count is less than 0.", Name)); + } + } + + /// + /// 释放对象。 + /// + /// 是否是关闭对象池时触发。 + public void Release(bool isShutdown) + { + m_Object.Release(isShutdown); + ReferencePool.Release(m_Object); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.Object.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.Object.cs.meta new file mode 100644 index 0000000..a399596 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.Object.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d25239d5d55ea74fb9c08d9d8b14f71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs new file mode 100644 index 0000000..0cee3a6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs @@ -0,0 +1,637 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.ObjectPool +{ + internal sealed partial class ObjectPoolManager : GameFrameworkModule, IObjectPoolManager + { + /// + /// 对象池。 + /// + /// 对象类型。 + private sealed class ObjectPool : ObjectPoolBase, IObjectPool where T : ObjectBase + { + private readonly GameFrameworkMultiDictionary> m_Objects; + private readonly Dictionary> m_ObjectMap; + private readonly ReleaseObjectFilterCallback m_DefaultReleaseObjectFilterCallback; + private readonly List m_CachedCanReleaseObjects; + private readonly List m_CachedToReleaseObjects; + private readonly bool m_AllowMultiSpawn; + private float m_AutoReleaseInterval; + private int m_Capacity; + private float m_ExpireTime; + private int m_Priority; + private float m_AutoReleaseTime; + + /// + /// 初始化对象池的新实例。 + /// + /// 对象池名称。 + /// 是否允许对象被多次获取。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + public ObjectPool(string name, bool allowMultiSpawn, float autoReleaseInterval, int capacity, float expireTime, int priority) + : base(name) + { + m_Objects = new GameFrameworkMultiDictionary>(); + m_ObjectMap = new Dictionary>(); + m_DefaultReleaseObjectFilterCallback = DefaultReleaseObjectFilterCallback; + m_CachedCanReleaseObjects = new List(); + m_CachedToReleaseObjects = new List(); + m_AllowMultiSpawn = allowMultiSpawn; + m_AutoReleaseInterval = autoReleaseInterval; + Capacity = capacity; + ExpireTime = expireTime; + m_Priority = priority; + m_AutoReleaseTime = 0f; + } + + /// + /// 获取对象池对象类型。 + /// + public override Type ObjectType + { + get + { + return typeof(T); + } + } + + /// + /// 获取对象池中对象的数量。 + /// + public override int Count + { + get + { + return m_ObjectMap.Count; + } + } + + /// + /// 获取对象池中能被释放的对象的数量。 + /// + public override int CanReleaseCount + { + get + { + GetCanReleaseObjects(m_CachedCanReleaseObjects); + return m_CachedCanReleaseObjects.Count; + } + } + + /// + /// 获取是否允许对象被多次获取。 + /// + public override bool AllowMultiSpawn + { + get + { + return m_AllowMultiSpawn; + } + } + + /// + /// 获取或设置对象池自动释放可释放对象的间隔秒数。 + /// + public override float AutoReleaseInterval + { + get + { + return m_AutoReleaseInterval; + } + set + { + m_AutoReleaseInterval = value; + } + } + + /// + /// 获取或设置对象池的容量。 + /// + public override int Capacity + { + get + { + return m_Capacity; + } + set + { + if (value < 0) + { + throw new GameFrameworkException("Capacity is invalid."); + } + + if (m_Capacity == value) + { + return; + } + + m_Capacity = value; + Release(); + } + } + + /// + /// 获取或设置对象池对象过期秒数。 + /// + public override float ExpireTime + { + get + { + return m_ExpireTime; + } + + set + { + if (value < 0f) + { + throw new GameFrameworkException("ExpireTime is invalid."); + } + + if (ExpireTime == value) + { + return; + } + + m_ExpireTime = value; + Release(); + } + } + + /// + /// 获取或设置对象池的优先级。 + /// + public override int Priority + { + get + { + return m_Priority; + } + set + { + m_Priority = value; + } + } + + /// + /// 创建对象。 + /// + /// 对象。 + /// 对象是否已被获取。 + public void Register(T obj, bool spawned) + { + if (obj == null) + { + throw new GameFrameworkException("Object is invalid."); + } + + Object internalObject = Object.Create(obj, spawned); + m_Objects.Add(obj.Name, internalObject); + m_ObjectMap.Add(obj.Target, internalObject); + + if (Count > m_Capacity) + { + Release(); + } + } + + /// + /// 检查对象。 + /// + /// 要检查的对象是否存在。 + public bool CanSpawn() + { + return CanSpawn(string.Empty); + } + + /// + /// 检查对象。 + /// + /// 对象名称。 + /// 要检查的对象是否存在。 + public bool CanSpawn(string name) + { + if (name == null) + { + throw new GameFrameworkException("Name is invalid."); + } + + GameFrameworkLinkedListRange> objectRange = default(GameFrameworkLinkedListRange>); + if (m_Objects.TryGetValue(name, out objectRange)) + { + foreach (Object internalObject in objectRange) + { + if (m_AllowMultiSpawn || !internalObject.IsInUse) + { + return true; + } + } + } + + return false; + } + + /// + /// 获取对象。 + /// + /// 要获取的对象。 + public T Spawn() + { + return Spawn(string.Empty); + } + + /// + /// 获取对象。 + /// + /// 对象名称。 + /// 要获取的对象。 + public T Spawn(string name) + { + if (name == null) + { + throw new GameFrameworkException("Name is invalid."); + } + + GameFrameworkLinkedListRange> objectRange = default(GameFrameworkLinkedListRange>); + if (m_Objects.TryGetValue(name, out objectRange)) + { + foreach (Object internalObject in objectRange) + { + if (m_AllowMultiSpawn || !internalObject.IsInUse) + { + return internalObject.Spawn(); + } + } + } + + return null; + } + + /// + /// 回收对象。 + /// + /// 要回收的对象。 + public void Unspawn(T obj) + { + if (obj == null) + { + throw new GameFrameworkException("Object is invalid."); + } + + Unspawn(obj.Target); + } + + /// + /// 回收对象。 + /// + /// 要回收的对象。 + public void Unspawn(object target) + { + if (target == null) + { + throw new GameFrameworkException("Target is invalid."); + } + + Object internalObject = GetObject(target); + if (internalObject != null) + { + internalObject.Unspawn(); + if (Count > m_Capacity && internalObject.SpawnCount <= 0) + { + Release(); + } + } + else + { + throw new GameFrameworkException(Utility.Text.Format("Can not find target in object pool '{0}', target type is '{1}', target value is '{2}'.", new TypeNamePair(typeof(T), Name), target.GetType().FullName, target)); + } + } + + /// + /// 设置对象是否被加锁。 + /// + /// 要设置被加锁的对象。 + /// 是否被加锁。 + public void SetLocked(T obj, bool locked) + { + if (obj == null) + { + throw new GameFrameworkException("Object is invalid."); + } + + SetLocked(obj.Target, locked); + } + + /// + /// 设置对象是否被加锁。 + /// + /// 要设置被加锁的对象。 + /// 是否被加锁。 + public void SetLocked(object target, bool locked) + { + if (target == null) + { + throw new GameFrameworkException("Target is invalid."); + } + + Object internalObject = GetObject(target); + if (internalObject != null) + { + internalObject.Locked = locked; + } + else + { + throw new GameFrameworkException(Utility.Text.Format("Can not find target in object pool '{0}', target type is '{1}', target value is '{2}'.", new TypeNamePair(typeof(T), Name), target.GetType().FullName, target)); + } + } + + /// + /// 设置对象的优先级。 + /// + /// 要设置优先级的对象。 + /// 优先级。 + public void SetPriority(T obj, int priority) + { + if (obj == null) + { + throw new GameFrameworkException("Object is invalid."); + } + + SetPriority(obj.Target, priority); + } + + /// + /// 设置对象的优先级。 + /// + /// 要设置优先级的对象。 + /// 优先级。 + public void SetPriority(object target, int priority) + { + if (target == null) + { + throw new GameFrameworkException("Target is invalid."); + } + + Object internalObject = GetObject(target); + if (internalObject != null) + { + internalObject.Priority = priority; + } + else + { + throw new GameFrameworkException(Utility.Text.Format("Can not find target in object pool '{0}', target type is '{1}', target value is '{2}'.", new TypeNamePair(typeof(T), Name), target.GetType().FullName, target)); + } + } + + /// + /// 释放对象。 + /// + /// 要释放的对象。 + /// 释放对象是否成功。 + public bool ReleaseObject(T obj) + { + if (obj == null) + { + throw new GameFrameworkException("Object is invalid."); + } + + return ReleaseObject(obj.Target); + } + + /// + /// 释放对象。 + /// + /// 要释放的对象。 + /// 释放对象是否成功。 + public bool ReleaseObject(object target) + { + if (target == null) + { + throw new GameFrameworkException("Target is invalid."); + } + + Object internalObject = GetObject(target); + if (internalObject == null) + { + return false; + } + + if (internalObject.IsInUse || internalObject.Locked || !internalObject.CustomCanReleaseFlag) + { + return false; + } + + m_Objects.Remove(internalObject.Name, internalObject); + m_ObjectMap.Remove(internalObject.Peek().Target); + + internalObject.Release(false); + ReferencePool.Release(internalObject); + return true; + } + + /// + /// 释放对象池中的可释放对象。 + /// + public override void Release() + { + Release(Count - m_Capacity, m_DefaultReleaseObjectFilterCallback); + } + + /// + /// 释放对象池中的可释放对象。 + /// + /// 尝试释放对象数量。 + public override void Release(int toReleaseCount) + { + Release(toReleaseCount, m_DefaultReleaseObjectFilterCallback); + } + + /// + /// 释放对象池中的可释放对象。 + /// + /// 释放对象筛选函数。 + public void Release(ReleaseObjectFilterCallback releaseObjectFilterCallback) + { + Release(Count - m_Capacity, releaseObjectFilterCallback); + } + + /// + /// 释放对象池中的可释放对象。 + /// + /// 尝试释放对象数量。 + /// 释放对象筛选函数。 + public void Release(int toReleaseCount, ReleaseObjectFilterCallback releaseObjectFilterCallback) + { + if (releaseObjectFilterCallback == null) + { + throw new GameFrameworkException("Release object filter callback is invalid."); + } + + if (toReleaseCount < 0) + { + toReleaseCount = 0; + } + + DateTime expireTime = DateTime.MinValue; + if (m_ExpireTime < float.MaxValue) + { + expireTime = DateTime.UtcNow.AddSeconds(-m_ExpireTime); + } + + m_AutoReleaseTime = 0f; + GetCanReleaseObjects(m_CachedCanReleaseObjects); + List toReleaseObjects = releaseObjectFilterCallback(m_CachedCanReleaseObjects, toReleaseCount, expireTime); + if (toReleaseObjects == null || toReleaseObjects.Count <= 0) + { + return; + } + + foreach (T toReleaseObject in toReleaseObjects) + { + ReleaseObject(toReleaseObject); + } + } + + /// + /// 释放对象池中的所有未使用对象。 + /// + public override void ReleaseAllUnused() + { + m_AutoReleaseTime = 0f; + GetCanReleaseObjects(m_CachedCanReleaseObjects); + foreach (T toReleaseObject in m_CachedCanReleaseObjects) + { + ReleaseObject(toReleaseObject); + } + } + + /// + /// 获取所有对象信息。 + /// + /// 所有对象信息。 + public override ObjectInfo[] GetAllObjectInfos() + { + List results = new List(); + foreach (KeyValuePair>> objectRanges in m_Objects) + { + foreach (Object internalObject in objectRanges.Value) + { + results.Add(new ObjectInfo(internalObject.Name, internalObject.Locked, internalObject.CustomCanReleaseFlag, internalObject.Priority, internalObject.LastUseTime, internalObject.SpawnCount)); + } + } + + return results.ToArray(); + } + + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + m_AutoReleaseTime += realElapseSeconds; + if (m_AutoReleaseTime < m_AutoReleaseInterval) + { + return; + } + + Release(); + } + + internal override void Shutdown() + { + foreach (KeyValuePair> objectInMap in m_ObjectMap) + { + objectInMap.Value.Release(true); + ReferencePool.Release(objectInMap.Value); + } + + m_Objects.Clear(); + m_ObjectMap.Clear(); + m_CachedCanReleaseObjects.Clear(); + m_CachedToReleaseObjects.Clear(); + } + + private Object GetObject(object target) + { + if (target == null) + { + throw new GameFrameworkException("Target is invalid."); + } + + Object internalObject = null; + if (m_ObjectMap.TryGetValue(target, out internalObject)) + { + return internalObject; + } + + return null; + } + + private void GetCanReleaseObjects(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair> objectInMap in m_ObjectMap) + { + Object internalObject = objectInMap.Value; + if (internalObject.IsInUse || internalObject.Locked || !internalObject.CustomCanReleaseFlag) + { + continue; + } + + results.Add(internalObject.Peek()); + } + } + + private List DefaultReleaseObjectFilterCallback(List candidateObjects, int toReleaseCount, DateTime expireTime) + { + m_CachedToReleaseObjects.Clear(); + + if (expireTime > DateTime.MinValue) + { + for (int i = candidateObjects.Count - 1; i >= 0; i--) + { + if (candidateObjects[i].LastUseTime <= expireTime) + { + m_CachedToReleaseObjects.Add(candidateObjects[i]); + candidateObjects.RemoveAt(i); + continue; + } + } + + toReleaseCount -= m_CachedToReleaseObjects.Count; + } + + for (int i = 0; toReleaseCount > 0 && i < candidateObjects.Count; i++) + { + for (int j = i + 1; j < candidateObjects.Count; j++) + { + if (candidateObjects[i].Priority > candidateObjects[j].Priority + || candidateObjects[i].Priority == candidateObjects[j].Priority && candidateObjects[i].LastUseTime > candidateObjects[j].LastUseTime) + { + T temp = candidateObjects[i]; + candidateObjects[i] = candidateObjects[j]; + candidateObjects[j] = temp; + } + } + + m_CachedToReleaseObjects.Add(candidateObjects[i]); + toReleaseCount--; + } + + return m_CachedToReleaseObjects; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs.meta new file mode 100644 index 0000000..ed5ac4a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b63a7ea745699464db6e85a2535c2a56 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.cs new file mode 100644 index 0000000..9ec71bf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.cs @@ -0,0 +1,1303 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.ObjectPool +{ + /// + /// 对象池管理器。 + /// + internal sealed partial class ObjectPoolManager : GameFrameworkModule, IObjectPoolManager + { + private const int DefaultCapacity = int.MaxValue; + private const float DefaultExpireTime = float.MaxValue; + private const int DefaultPriority = 0; + + private readonly Dictionary m_ObjectPools; + private readonly List m_CachedAllObjectPools; + private readonly Comparison m_ObjectPoolComparer; + + /// + /// 初始化对象池管理器的新实例。 + /// + public ObjectPoolManager() + { + m_ObjectPools = new Dictionary(); + m_CachedAllObjectPools = new List(); + m_ObjectPoolComparer = ObjectPoolComparer; + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return 6; + } + } + + /// + /// 获取对象池数量。 + /// + public int Count + { + get + { + return m_ObjectPools.Count; + } + } + + /// + /// 对象池管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + foreach (KeyValuePair objectPool in m_ObjectPools) + { + objectPool.Value.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理对象池管理器。 + /// + internal override void Shutdown() + { + foreach (KeyValuePair objectPool in m_ObjectPools) + { + objectPool.Value.Shutdown(); + } + + m_ObjectPools.Clear(); + m_CachedAllObjectPools.Clear(); + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 是否存在对象池。 + public bool HasObjectPool() where T : ObjectBase + { + return InternalHasObjectPool(new TypeNamePair(typeof(T))); + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 是否存在对象池。 + public bool HasObjectPool(Type objectType) + { + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (!typeof(ObjectBase).IsAssignableFrom(objectType)) + { + throw new GameFrameworkException(Utility.Text.Format("Object type '{0}' is invalid.", objectType.FullName)); + } + + return InternalHasObjectPool(new TypeNamePair(objectType)); + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 是否存在对象池。 + public bool HasObjectPool(string name) where T : ObjectBase + { + return InternalHasObjectPool(new TypeNamePair(typeof(T), name)); + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 是否存在对象池。 + public bool HasObjectPool(Type objectType, string name) + { + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (!typeof(ObjectBase).IsAssignableFrom(objectType)) + { + throw new GameFrameworkException(Utility.Text.Format("Object type '{0}' is invalid.", objectType.FullName)); + } + + return InternalHasObjectPool(new TypeNamePair(objectType, name)); + } + + /// + /// 检查是否存在对象池。 + /// + /// 要检查的条件。 + /// 是否存在对象池。 + public bool HasObjectPool(Predicate condition) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + foreach (KeyValuePair objectPool in m_ObjectPools) + { + if (condition(objectPool.Value)) + { + return true; + } + } + + return false; + } + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 要获取的对象池。 + public IObjectPool GetObjectPool() where T : ObjectBase + { + return (IObjectPool)InternalGetObjectPool(new TypeNamePair(typeof(T))); + } + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 要获取的对象池。 + public ObjectPoolBase GetObjectPool(Type objectType) + { + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (!typeof(ObjectBase).IsAssignableFrom(objectType)) + { + throw new GameFrameworkException(Utility.Text.Format("Object type '{0}' is invalid.", objectType.FullName)); + } + + return InternalGetObjectPool(new TypeNamePair(objectType)); + } + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要获取的对象池。 + public IObjectPool GetObjectPool(string name) where T : ObjectBase + { + return (IObjectPool)InternalGetObjectPool(new TypeNamePair(typeof(T), name)); + } + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要获取的对象池。 + public ObjectPoolBase GetObjectPool(Type objectType, string name) + { + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (!typeof(ObjectBase).IsAssignableFrom(objectType)) + { + throw new GameFrameworkException(Utility.Text.Format("Object type '{0}' is invalid.", objectType.FullName)); + } + + return InternalGetObjectPool(new TypeNamePair(objectType, name)); + } + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + public ObjectPoolBase GetObjectPool(Predicate condition) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + foreach (KeyValuePair objectPool in m_ObjectPools) + { + if (condition(objectPool.Value)) + { + return objectPool.Value; + } + } + + return null; + } + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + public ObjectPoolBase[] GetObjectPools(Predicate condition) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + List results = new List(); + foreach (KeyValuePair objectPool in m_ObjectPools) + { + if (condition(objectPool.Value)) + { + results.Add(objectPool.Value); + } + } + + return results.ToArray(); + } + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + public void GetObjectPools(Predicate condition, List results) + { + if (condition == null) + { + throw new GameFrameworkException("Condition is invalid."); + } + + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair objectPool in m_ObjectPools) + { + if (condition(objectPool.Value)) + { + results.Add(objectPool.Value); + } + } + } + + /// + /// 获取所有对象池。 + /// + /// 所有对象池。 + public ObjectPoolBase[] GetAllObjectPools() + { + return GetAllObjectPools(false); + } + + /// + /// 获取所有对象池。 + /// + /// 所有对象池。 + public void GetAllObjectPools(List results) + { + GetAllObjectPools(false, results); + } + + /// + /// 获取所有对象池。 + /// + /// 是否根据对象池的优先级排序。 + /// 所有对象池。 + public ObjectPoolBase[] GetAllObjectPools(bool sort) + { + if (sort) + { + List results = new List(); + foreach (KeyValuePair objectPool in m_ObjectPools) + { + results.Add(objectPool.Value); + } + + results.Sort(m_ObjectPoolComparer); + return results.ToArray(); + } + else + { + int index = 0; + ObjectPoolBase[] results = new ObjectPoolBase[m_ObjectPools.Count]; + foreach (KeyValuePair objectPool in m_ObjectPools) + { + results[index++] = objectPool.Value; + } + + return results; + } + } + + /// + /// 获取所有对象池。 + /// + /// 是否根据对象池的优先级排序。 + /// 所有对象池。 + public void GetAllObjectPools(bool sort, List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair objectPool in m_ObjectPools) + { + results.Add(objectPool.Value); + } + + if (sort) + { + results.Sort(m_ObjectPoolComparer); + } + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool() where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, false, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType) + { + return InternalCreateObjectPool(objectType, string.Empty, false, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name) where T : ObjectBase + { + return InternalCreateObjectPool(name, false, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name) + { + return InternalCreateObjectPool(objectType, name, false, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(int capacity) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, false, DefaultExpireTime, capacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity) + { + return InternalCreateObjectPool(objectType, string.Empty, false, DefaultExpireTime, capacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(float expireTime) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, false, expireTime, DefaultCapacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime) + { + return InternalCreateObjectPool(objectType, string.Empty, false, expireTime, DefaultCapacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, int capacity) where T : ObjectBase + { + return InternalCreateObjectPool(name, false, DefaultExpireTime, capacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity) + { + return InternalCreateObjectPool(objectType, name, false, DefaultExpireTime, capacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, float expireTime) where T : ObjectBase + { + return InternalCreateObjectPool(name, false, expireTime, DefaultCapacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime) + { + return InternalCreateObjectPool(objectType, name, false, expireTime, DefaultCapacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(int capacity, float expireTime) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, false, expireTime, capacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime) + { + return InternalCreateObjectPool(objectType, string.Empty, false, expireTime, capacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(int capacity, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, false, DefaultExpireTime, capacity, DefaultExpireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, int priority) + { + return InternalCreateObjectPool(objectType, string.Empty, false, DefaultExpireTime, capacity, DefaultExpireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, false, expireTime, DefaultCapacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, string.Empty, false, expireTime, DefaultCapacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, float expireTime) where T : ObjectBase + { + return InternalCreateObjectPool(name, false, expireTime, capacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime) + { + return InternalCreateObjectPool(objectType, name, false, expireTime, capacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(name, false, DefaultExpireTime, capacity, DefaultExpireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, int priority) + { + return InternalCreateObjectPool(objectType, name, false, DefaultExpireTime, capacity, DefaultExpireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(name, false, expireTime, DefaultCapacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, name, false, expireTime, DefaultCapacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(int capacity, float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, false, expireTime, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, string.Empty, false, expireTime, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(name, false, expireTime, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, name, false, expireTime, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(name, false, autoReleaseInterval, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, name, false, autoReleaseInterval, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool() where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, true, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType) + { + return InternalCreateObjectPool(objectType, string.Empty, true, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name) where T : ObjectBase + { + return InternalCreateObjectPool(name, true, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name) + { + return InternalCreateObjectPool(objectType, name, true, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(int capacity) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, true, DefaultExpireTime, capacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity) + { + return InternalCreateObjectPool(objectType, string.Empty, true, DefaultExpireTime, capacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(float expireTime) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, true, expireTime, DefaultCapacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime) + { + return InternalCreateObjectPool(objectType, string.Empty, true, expireTime, DefaultCapacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, int capacity) where T : ObjectBase + { + return InternalCreateObjectPool(name, true, DefaultExpireTime, capacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity) + { + return InternalCreateObjectPool(objectType, name, true, DefaultExpireTime, capacity, DefaultExpireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, float expireTime) where T : ObjectBase + { + return InternalCreateObjectPool(name, true, expireTime, DefaultCapacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime) + { + return InternalCreateObjectPool(objectType, name, true, expireTime, DefaultCapacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(int capacity, float expireTime) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, true, expireTime, capacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime) + { + return InternalCreateObjectPool(objectType, string.Empty, true, expireTime, capacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(int capacity, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, true, DefaultExpireTime, capacity, DefaultExpireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, int priority) + { + return InternalCreateObjectPool(objectType, string.Empty, true, DefaultExpireTime, capacity, DefaultExpireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, true, expireTime, DefaultCapacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, string.Empty, true, expireTime, DefaultCapacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, float expireTime) where T : ObjectBase + { + return InternalCreateObjectPool(name, true, expireTime, capacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime) + { + return InternalCreateObjectPool(objectType, name, true, expireTime, capacity, expireTime, DefaultPriority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(name, true, DefaultExpireTime, capacity, DefaultExpireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, int priority) + { + return InternalCreateObjectPool(objectType, name, true, DefaultExpireTime, capacity, DefaultExpireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(name, true, expireTime, DefaultCapacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, name, true, expireTime, DefaultCapacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(int capacity, float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(string.Empty, true, expireTime, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, string.Empty, true, expireTime, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(name, true, expireTime, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, name, true, expireTime, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase + { + return InternalCreateObjectPool(name, true, autoReleaseInterval, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority) + { + return InternalCreateObjectPool(objectType, name, true, autoReleaseInterval, capacity, expireTime, priority); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool() where T : ObjectBase + { + return InternalDestroyObjectPool(new TypeNamePair(typeof(T))); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(Type objectType) + { + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (!typeof(ObjectBase).IsAssignableFrom(objectType)) + { + throw new GameFrameworkException(Utility.Text.Format("Object type '{0}' is invalid.", objectType.FullName)); + } + + return InternalDestroyObjectPool(new TypeNamePair(objectType)); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池名称。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(string name) where T : ObjectBase + { + return InternalDestroyObjectPool(new TypeNamePair(typeof(T), name)); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池名称。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(Type objectType, string name) + { + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (!typeof(ObjectBase).IsAssignableFrom(objectType)) + { + throw new GameFrameworkException(Utility.Text.Format("Object type '{0}' is invalid.", objectType.FullName)); + } + + return InternalDestroyObjectPool(new TypeNamePair(objectType, name)); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(IObjectPool objectPool) where T : ObjectBase + { + if (objectPool == null) + { + throw new GameFrameworkException("Object pool is invalid."); + } + + return InternalDestroyObjectPool(new TypeNamePair(typeof(T), objectPool.Name)); + } + + /// + /// 销毁对象池。 + /// + /// 要销毁的对象池。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(ObjectPoolBase objectPool) + { + if (objectPool == null) + { + throw new GameFrameworkException("Object pool is invalid."); + } + + return InternalDestroyObjectPool(new TypeNamePair(objectPool.ObjectType, objectPool.Name)); + } + + /// + /// 释放对象池中的可释放对象。 + /// + public void Release() + { + GetAllObjectPools(true, m_CachedAllObjectPools); + foreach (ObjectPoolBase objectPool in m_CachedAllObjectPools) + { + objectPool.Release(); + } + } + + /// + /// 释放对象池中的所有未使用对象。 + /// + public void ReleaseAllUnused() + { + GetAllObjectPools(true, m_CachedAllObjectPools); + foreach (ObjectPoolBase objectPool in m_CachedAllObjectPools) + { + objectPool.ReleaseAllUnused(); + } + } + + private bool InternalHasObjectPool(TypeNamePair typeNamePair) + { + return m_ObjectPools.ContainsKey(typeNamePair); + } + + private ObjectPoolBase InternalGetObjectPool(TypeNamePair typeNamePair) + { + ObjectPoolBase objectPool = null; + if (m_ObjectPools.TryGetValue(typeNamePair, out objectPool)) + { + return objectPool; + } + + return null; + } + + private IObjectPool InternalCreateObjectPool(string name, bool allowMultiSpawn, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase + { + TypeNamePair typeNamePair = new TypeNamePair(typeof(T), name); + if (HasObjectPool(name)) + { + throw new GameFrameworkException(Utility.Text.Format("Already exist object pool '{0}'.", typeNamePair)); + } + + ObjectPool objectPool = new ObjectPool(name, allowMultiSpawn, autoReleaseInterval, capacity, expireTime, priority); + m_ObjectPools.Add(typeNamePair, objectPool); + return objectPool; + } + + private ObjectPoolBase InternalCreateObjectPool(Type objectType, string name, bool allowMultiSpawn, float autoReleaseInterval, int capacity, float expireTime, int priority) + { + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (!typeof(ObjectBase).IsAssignableFrom(objectType)) + { + throw new GameFrameworkException(Utility.Text.Format("Object type '{0}' is invalid.", objectType.FullName)); + } + + TypeNamePair typeNamePair = new TypeNamePair(objectType, name); + if (HasObjectPool(objectType, name)) + { + throw new GameFrameworkException(Utility.Text.Format("Already exist object pool '{0}'.", typeNamePair)); + } + + Type objectPoolType = typeof(ObjectPool<>).MakeGenericType(objectType); + ObjectPoolBase objectPool = (ObjectPoolBase)Activator.CreateInstance(objectPoolType, name, allowMultiSpawn, autoReleaseInterval, capacity, expireTime, priority); + m_ObjectPools.Add(typeNamePair, objectPool); + return objectPool; + } + + private bool InternalDestroyObjectPool(TypeNamePair typeNamePair) + { + ObjectPoolBase objectPool = null; + if (m_ObjectPools.TryGetValue(typeNamePair, out objectPool)) + { + objectPool.Shutdown(); + return m_ObjectPools.Remove(typeNamePair); + } + + return false; + } + + private static int ObjectPoolComparer(ObjectPoolBase a, ObjectPoolBase b) + { + return a.Priority.CompareTo(b.Priority); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.cs.meta new file mode 100644 index 0000000..8b8dc2d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ObjectPoolManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fe6f236a504e4540be4c54618813794 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ReleaseObjectFilterCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ReleaseObjectFilterCallback.cs new file mode 100644 index 0000000..a14a741 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ReleaseObjectFilterCallback.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.ObjectPool +{ + /// + /// 释放对象筛选函数。 + /// + /// 对象类型。 + /// 要筛选的对象集合。 + /// 需要释放的对象数量。 + /// 对象过期参考时间。 + /// 经筛选需要释放的对象集合。 + public delegate List ReleaseObjectFilterCallback(List candidateObjects, int toReleaseCount, DateTime expireTime) where T : ObjectBase; +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ReleaseObjectFilterCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ReleaseObjectFilterCallback.cs.meta new file mode 100644 index 0000000..c4220ed --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/ObjectPool/ReleaseObjectFilterCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 316950f903642e140b28a98d191593d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure.meta new file mode 100644 index 0000000..09c2911 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 93f42ccdf732d444eb45acfdebe91cf3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/IProcedureManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/IProcedureManager.cs new file mode 100644 index 0000000..0a07dcc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/IProcedureManager.cs @@ -0,0 +1,81 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Fsm; +using System; + +namespace GameFramework.Procedure +{ + /// + /// 流程管理器接口。 + /// + public interface IProcedureManager + { + /// + /// 获取当前流程。 + /// + ProcedureBase CurrentProcedure + { + get; + } + + /// + /// 获取当前流程持续时间。 + /// + float CurrentProcedureTime + { + get; + } + + /// + /// 初始化流程管理器。 + /// + /// 有限状态机管理器。 + /// 流程管理器包含的流程。 + void Initialize(IFsmManager fsmManager, params ProcedureBase[] procedures); + + /// + /// 开始流程。 + /// + /// 要开始的流程类型。 + void StartProcedure() where T : ProcedureBase; + + /// + /// 开始流程。 + /// + /// 要开始的流程类型。 + void StartProcedure(Type procedureType); + + /// + /// 是否存在流程。 + /// + /// 要检查的流程类型。 + /// 是否存在流程。 + bool HasProcedure() where T : ProcedureBase; + + /// + /// 是否存在流程。 + /// + /// 要检查的流程类型。 + /// 是否存在流程。 + bool HasProcedure(Type procedureType); + + /// + /// 获取流程。 + /// + /// 要获取的流程类型。 + /// 要获取的流程。 + ProcedureBase GetProcedure() where T : ProcedureBase; + + /// + /// 获取流程。 + /// + /// 要获取的流程类型。 + /// 要获取的流程。 + ProcedureBase GetProcedure(Type procedureType); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/IProcedureManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/IProcedureManager.cs.meta new file mode 100644 index 0000000..ec5a277 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/IProcedureManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a4634353942ca3345a4b6f8854aff84f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureBase.cs new file mode 100644 index 0000000..fe12b37 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureBase.cs @@ -0,0 +1,66 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Fsm; +using ProcedureOwner = GameFramework.Fsm.IFsm; + +namespace GameFramework.Procedure +{ + /// + /// 流程基类。 + /// + public abstract class ProcedureBase : FsmState + { + /// + /// 状态初始化时调用。 + /// + /// 流程持有者。 + protected internal override void OnInit(ProcedureOwner procedureOwner) + { + base.OnInit(procedureOwner); + } + + /// + /// 进入状态时调用。 + /// + /// 流程持有者。 + protected internal override void OnEnter(ProcedureOwner procedureOwner) + { + base.OnEnter(procedureOwner); + } + + /// + /// 状态轮询时调用。 + /// + /// 流程持有者。 + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + protected internal override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds) + { + base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds); + } + + /// + /// 离开状态时调用。 + /// + /// 流程持有者。 + /// 是否是关闭状态机时触发。 + protected internal override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown) + { + base.OnLeave(procedureOwner, isShutdown); + } + + /// + /// 状态销毁时调用。 + /// + /// 流程持有者。 + protected internal override void OnDestroy(ProcedureOwner procedureOwner) + { + base.OnDestroy(procedureOwner); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureBase.cs.meta new file mode 100644 index 0000000..34f4ce0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 034fbfe11d07865408f726f3e06434b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureManager.cs new file mode 100644 index 0000000..8741258 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureManager.cs @@ -0,0 +1,204 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Fsm; +using System; + +namespace GameFramework.Procedure +{ + /// + /// 流程管理器。 + /// + internal sealed class ProcedureManager : GameFrameworkModule, IProcedureManager + { + private IFsmManager m_FsmManager; + private IFsm m_ProcedureFsm; + + /// + /// 初始化流程管理器的新实例。 + /// + public ProcedureManager() + { + m_FsmManager = null; + m_ProcedureFsm = null; + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return -2; + } + } + + /// + /// 获取当前流程。 + /// + public ProcedureBase CurrentProcedure + { + get + { + if (m_ProcedureFsm == null) + { + throw new GameFrameworkException("You must initialize procedure first."); + } + + return (ProcedureBase)m_ProcedureFsm.CurrentState; + } + } + + /// + /// 获取当前流程持续时间。 + /// + public float CurrentProcedureTime + { + get + { + if (m_ProcedureFsm == null) + { + throw new GameFrameworkException("You must initialize procedure first."); + } + + return m_ProcedureFsm.CurrentStateTime; + } + } + + /// + /// 流程管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理流程管理器。 + /// + internal override void Shutdown() + { + if (m_FsmManager != null) + { + if (m_ProcedureFsm != null) + { + m_FsmManager.DestroyFsm(m_ProcedureFsm); + m_ProcedureFsm = null; + } + + m_FsmManager = null; + } + } + + /// + /// 初始化流程管理器。 + /// + /// 有限状态机管理器。 + /// 流程管理器包含的流程。 + public void Initialize(IFsmManager fsmManager, params ProcedureBase[] procedures) + { + if (fsmManager == null) + { + throw new GameFrameworkException("FSM manager is invalid."); + } + + m_FsmManager = fsmManager; + m_ProcedureFsm = m_FsmManager.CreateFsm(this, procedures); + } + + /// + /// 开始流程。 + /// + /// 要开始的流程类型。 + public void StartProcedure() where T : ProcedureBase + { + if (m_ProcedureFsm == null) + { + throw new GameFrameworkException("You must initialize procedure first."); + } + + m_ProcedureFsm.Start(); + } + + /// + /// 开始流程。 + /// + /// 要开始的流程类型。 + public void StartProcedure(Type procedureType) + { + if (m_ProcedureFsm == null) + { + throw new GameFrameworkException("You must initialize procedure first."); + } + + m_ProcedureFsm.Start(procedureType); + } + + /// + /// 是否存在流程。 + /// + /// 要检查的流程类型。 + /// 是否存在流程。 + public bool HasProcedure() where T : ProcedureBase + { + if (m_ProcedureFsm == null) + { + throw new GameFrameworkException("You must initialize procedure first."); + } + + return m_ProcedureFsm.HasState(); + } + + /// + /// 是否存在流程。 + /// + /// 要检查的流程类型。 + /// 是否存在流程。 + public bool HasProcedure(Type procedureType) + { + if (m_ProcedureFsm == null) + { + throw new GameFrameworkException("You must initialize procedure first."); + } + + return m_ProcedureFsm.HasState(procedureType); + } + + /// + /// 获取流程。 + /// + /// 要获取的流程类型。 + /// 要获取的流程。 + public ProcedureBase GetProcedure() where T : ProcedureBase + { + if (m_ProcedureFsm == null) + { + throw new GameFrameworkException("You must initialize procedure first."); + } + + return m_ProcedureFsm.GetState(); + } + + /// + /// 获取流程。 + /// + /// 要获取的流程类型。 + /// 要获取的流程。 + public ProcedureBase GetProcedure(Type procedureType) + { + if (m_ProcedureFsm == null) + { + throw new GameFrameworkException("You must initialize procedure first."); + } + + return (ProcedureBase)m_ProcedureFsm.GetState(procedureType); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureManager.cs.meta new file mode 100644 index 0000000..8cb020f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Procedure/ProcedureManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c71102ea3b618ee428cac01413a34a3c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties.meta new file mode 100644 index 0000000..72badde --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f1103f49fa0c4ea4a9adb776206038b3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties/AssemblyInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7ba21ca --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties/AssemblyInfo.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Reflection; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下控制。更改这些特性值可修改与程序集关联的信息。 +[assembly: AssemblyTitle("Game Framework")] +[assembly: AssemblyDescription("Game Framework")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Jiang Yin")] +[assembly: AssemblyProduct("Game Framework")] +[assembly: AssemblyCopyright("Copyright © 2013-2021 Jiang Yin")] +[assembly: AssemblyTrademark("Copyright © 2013-2021 Jiang Yin")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 将使此程序集中的类型对 COM 组件不可见。 +// 如果需要从 COM 访问此程序集中的类型,请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID。 +[assembly: Guid("109d7f39-79ab-4862-9f73-0b8c638930c6")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: AssemblyFileVersion("0.0.0.0")] diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties/AssemblyInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties/AssemblyInfo.cs.meta new file mode 100644 index 0000000..d55b663 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Properties/AssemblyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9894300a237340c449a5a61a97c5528c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource.meta new file mode 100644 index 0000000..e33e842 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 548190345212e474b9b0d55b43627105 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ApplyResourcesCompleteCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ApplyResourcesCompleteCallback.cs new file mode 100644 index 0000000..ac3cf34 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ApplyResourcesCompleteCallback.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 使用可更新模式并应用资源包资源完成时的回调函数。 + /// + /// 应用的资源包路径。 + /// 应用资源包资源结果,全部成功为 true,否则为 false。 + public delegate void ApplyResourcesCompleteCallback(string resourcePackPath, bool result); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ApplyResourcesCompleteCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ApplyResourcesCompleteCallback.cs.meta new file mode 100644 index 0000000..d09b76c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ApplyResourcesCompleteCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9d27a65d627b6c4facd67c3371e85f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckResourcesCompleteCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckResourcesCompleteCallback.cs new file mode 100644 index 0000000..5077a9a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckResourcesCompleteCallback.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 使用可更新模式并检查资源完成时的回调函数。 + /// + /// 已移动的资源数量。 + /// 已移除的资源数量。 + /// 可更新的资源数量。 + /// 可更新的资源总大小。 + /// 可更新的压缩后总大小。 + public delegate void CheckResourcesCompleteCallback(int movedCount, int removedCount, int updateCount, long updateTotalLength, long updateTotalCompressedLength); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckResourcesCompleteCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckResourcesCompleteCallback.cs.meta new file mode 100644 index 0000000..aab0b02 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckResourcesCompleteCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44b378c75bd47654e8269f1a95775e36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckVersionListResult.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckVersionListResult.cs new file mode 100644 index 0000000..5ca6d37 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckVersionListResult.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 检查版本资源列表结果。 + /// + public enum CheckVersionListResult : byte + { + /// + /// 已经是最新的。 + /// + Updated = 0, + + /// + /// 需要更新。 + /// + NeedUpdate + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckVersionListResult.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckVersionListResult.cs.meta new file mode 100644 index 0000000..a9bfc16 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/CheckVersionListResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0011c07ad50f9d4428874a8b1191e5af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/Constant.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/Constant.cs new file mode 100644 index 0000000..7cda805 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/Constant.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源相关常量。 + /// + internal static class Constant + { + /// + /// 默认资源加载优先级。 + /// + internal const int DefaultPriority = 0; + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/Constant.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/Constant.cs.meta new file mode 100644 index 0000000..c462ec9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/Constant.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8568e897065730448853b7e92432a01a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/DecryptResourceCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/DecryptResourceCallback.cs new file mode 100644 index 0000000..88febfe --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/DecryptResourceCallback.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 解密资源回调函数。 + /// + /// 要解密的资源二进制流。 + /// 解密二进制流的起始位置。 + /// 解密二进制流的长度。 + /// 资源名称。 + /// 变体名称。 + /// 扩展名称。 + /// 资源是否在只读区。 + /// 文件系统名称。 + /// 资源加载方式。 + /// 资源大小。 + /// 资源哈希值。 + public delegate void DecryptResourceCallback(byte[] bytes, int startIndex, int count, string name, string variant, string extension, bool storageInReadOnly, string fileSystem, byte loadType, int length, int hashCode); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/DecryptResourceCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/DecryptResourceCallback.cs.meta new file mode 100644 index 0000000..6bf8649 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/DecryptResourceCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ff1c45ec7e055346aab3793b995ce9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/HasAssetResult.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/HasAssetResult.cs new file mode 100644 index 0000000..ca472de --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/HasAssetResult.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 检查资源是否存在的结果。 + /// + public enum HasAssetResult : byte + { + /// + /// 资源不存在。 + /// + NotExist = 0, + + /// + /// 资源尚未准备完毕。 + /// + NotReady, + + /// + /// 存在资源且存储在磁盘上。 + /// + AssetOnDisk, + + /// + /// 存在资源且存储在文件系统里。 + /// + AssetOnFileSystem, + + /// + /// 存在二进制资源且存储在磁盘上。 + /// + BinaryOnDisk, + + /// + /// 存在二进制资源且存储在文件系统里。 + /// + BinaryOnFileSystem + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/HasAssetResult.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/HasAssetResult.cs.meta new file mode 100644 index 0000000..49bcdc5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/HasAssetResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20a6f68e61643af4f97dc4bc326a65be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ILoadResourceAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ILoadResourceAgentHelper.cs new file mode 100644 index 0000000..a01b1cb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ILoadResourceAgentHelper.cs @@ -0,0 +1,94 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; +using System; + +namespace GameFramework.Resource +{ + /// + /// 加载资源代理辅助器接口。 + /// + public interface ILoadResourceAgentHelper + { + /// + /// 加载资源代理辅助器异步加载资源更新事件。 + /// + event EventHandler LoadResourceAgentHelperUpdate; + + /// + /// 加载资源代理辅助器异步读取资源文件完成事件。 + /// + event EventHandler LoadResourceAgentHelperReadFileComplete; + + /// + /// 加载资源代理辅助器异步读取资源二进制流完成事件。 + /// + event EventHandler LoadResourceAgentHelperReadBytesComplete; + + /// + /// 加载资源代理辅助器异步将资源二进制流转换为加载对象完成事件。 + /// + event EventHandler LoadResourceAgentHelperParseBytesComplete; + + /// + /// 加载资源代理辅助器异步加载资源完成事件。 + /// + event EventHandler LoadResourceAgentHelperLoadComplete; + + /// + /// 加载资源代理辅助器错误事件。 + /// + event EventHandler LoadResourceAgentHelperError; + + /// + /// 通过加载资源代理辅助器开始异步读取资源文件。 + /// + /// 要加载资源的完整路径名。 + void ReadFile(string fullPath); + + /// + /// 通过加载资源代理辅助器开始异步读取资源文件。 + /// + /// 要加载资源的文件系统。 + /// 要加载资源的名称。 + void ReadFile(IFileSystem fileSystem, string name); + + /// + /// 通过加载资源代理辅助器开始异步读取资源二进制流。 + /// + /// 要加载资源的完整路径名。 + void ReadBytes(string fullPath); + + /// + /// 通过加载资源代理辅助器开始异步读取资源二进制流。 + /// + /// 要加载资源的文件系统。 + /// 要加载资源的名称。 + void ReadBytes(IFileSystem fileSystem, string name); + + /// + /// 通过加载资源代理辅助器开始异步将资源二进制流转换为加载对象。 + /// + /// 要加载资源的二进制流。 + void ParseBytes(byte[] bytes); + + /// + /// 通过加载资源代理辅助器开始异步加载资源。 + /// + /// 资源。 + /// 要加载的资源名称。 + /// 要加载资源的类型。 + /// 要加载的资源是否是场景。 + void LoadAsset(object resource, string assetName, Type assetType, bool isScene); + + /// + /// 重置加载资源代理辅助器。 + /// + void Reset(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ILoadResourceAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ILoadResourceAgentHelper.cs.meta new file mode 100644 index 0000000..852f4ca --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ILoadResourceAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc60073224fc84140b3b9ce17514d213 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroup.cs new file mode 100644 index 0000000..fc42fd3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroup.cs @@ -0,0 +1,101 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + /// + /// 资源组接口。 + /// + public interface IResourceGroup + { + /// + /// 获取资源组名称。 + /// + string Name + { + get; + } + + /// + /// 获取资源组是否准备完毕。 + /// + bool Ready + { + get; + } + + /// + /// 获取资源组包含资源数量。 + /// + int TotalCount + { + get; + } + + /// + /// 获取资源组中已准备完成资源数量。 + /// + int ReadyCount + { + get; + } + + /// + /// 获取资源组包含资源的总大小。 + /// + long TotalLength + { + get; + } + + /// + /// 获取资源组包含资源压缩后的总大小。 + /// + long TotalCompressedLength + { + get; + } + + /// + /// 获取资源组中已准备完成资源的总大小。 + /// + long ReadyLength + { + get; + } + + /// + /// 获取资源组中已准备完成资源压缩后的总大小。 + /// + long ReadyCompressedLength + { + get; + } + + /// + /// 获取资源组的完成进度。 + /// + float Progress + { + get; + } + + /// + /// 获取资源组包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + string[] GetResourceNames(); + + /// + /// 获取资源组包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + void GetResourceNames(List results); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroup.cs.meta new file mode 100644 index 0000000..125812e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae9d786f449ccf5489209e287238c2fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroupCollection.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroupCollection.cs new file mode 100644 index 0000000..0ad3972 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroupCollection.cs @@ -0,0 +1,99 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + /// + /// 资源组集合接口。 + /// + public interface IResourceGroupCollection + { + /// + /// 获取资源组集合是否准备完毕。 + /// + bool Ready + { + get; + } + + /// + /// 获取资源组集合包含资源数量。 + /// + int TotalCount + { + get; + } + + /// + /// 获取资源组集合中已准备完成资源数量。 + /// + int ReadyCount + { + get; + } + + /// + /// 获取资源组集合包含资源的总大小。 + /// + long TotalLength + { + get; + } + + /// + /// 获取资源组集合包含资源压缩后的总大小。 + /// + long TotalCompressedLength + { + get; + } + + /// + /// 获取资源组集合中已准备完成资源的总大小。 + /// + long ReadyLength + { + get; + } + + /// + /// 获取资源组集合中已准备完成资源压缩后的总大小。 + /// + long ReadyCompressedLength + { + get; + } + + /// + /// 获取资源组集合的完成进度。 + /// + float Progress + { + get; + } + + /// + /// 获取资源组集合包含的资源组列表。 + /// + /// 资源组包含的资源名称列表。 + IResourceGroup[] GetResourceGroups(); + + /// + /// 获取资源组集合包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + string[] GetResourceNames(); + + /// + /// 获取资源组集合包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + void GetResourceNames(List results); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroupCollection.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroupCollection.cs.meta new file mode 100644 index 0000000..88b3266 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceGroupCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7ed56b1f5e4f9848998342ccd35e44c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceHelper.cs new file mode 100644 index 0000000..23b5e93 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceHelper.cs @@ -0,0 +1,37 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源辅助器接口。 + /// + public interface IResourceHelper + { + /// + /// 直接从指定文件路径加载数据流。 + /// + /// 文件路径。 + /// 加载数据流回调函数集。 + /// 用户自定义数据。 + void LoadBytes(string fileUri, LoadBytesCallbacks loadBytesCallbacks, object userData); + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + /// 卸载场景回调函数集。 + /// 用户自定义数据。 + void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData); + + /// + /// 释放资源。 + /// + /// 要释放的资源。 + void Release(object objectToRelease); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceHelper.cs.meta new file mode 100644 index 0000000..ca146a2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10986f8d788aa364a8147a56449ebf8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceManager.cs new file mode 100644 index 0000000..15ac7d7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceManager.cs @@ -0,0 +1,832 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Download; +using GameFramework.FileSystem; +using GameFramework.ObjectPool; +using System; +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + /// + /// 资源管理器接口。 + /// + public interface IResourceManager + { + /// + /// 获取资源只读区路径。 + /// + string ReadOnlyPath + { + get; + } + + /// + /// 获取资源读写区路径。 + /// + string ReadWritePath + { + get; + } + + /// + /// 获取资源模式。 + /// + ResourceMode ResourceMode + { + get; + } + + /// + /// 获取当前变体。 + /// + string CurrentVariant + { + get; + } + + /// + /// 获取单机模式版本资源列表序列化器。 + /// + PackageVersionListSerializer PackageVersionListSerializer + { + get; + } + + /// + /// 获取可更新模式版本资源列表序列化器。 + /// + UpdatableVersionListSerializer UpdatableVersionListSerializer + { + get; + } + + /// + /// 获取本地只读区版本资源列表序列化器。 + /// + ReadOnlyVersionListSerializer ReadOnlyVersionListSerializer + { + get; + } + + /// + /// 获取本地读写区版本资源列表序列化器。 + /// + ReadWriteVersionListSerializer ReadWriteVersionListSerializer + { + get; + } + + /// + /// 获取资源包版本资源列表序列化器。 + /// + ResourcePackVersionListSerializer ResourcePackVersionListSerializer + { + get; + } + + /// + /// 获取当前资源适用的游戏版本号。 + /// + string ApplicableGameVersion + { + get; + } + + /// + /// 获取当前内部资源版本号。 + /// + int InternalResourceVersion + { + get; + } + + /// + /// 获取资源数量。 + /// + int AssetCount + { + get; + } + + /// + /// 获取资源数量。 + /// + int ResourceCount + { + get; + } + + /// + /// 获取资源组数量。 + /// + int ResourceGroupCount + { + get; + } + + /// + /// 获取或设置资源更新下载地址。 + /// + string UpdatePrefixUri + { + get; + set; + } + + /// + /// 获取或设置每更新多少字节的资源,重新生成一次版本资源列表。 + /// + int GenerateReadWriteVersionListLength + { + get; + set; + } + + /// + /// 获取正在应用的资源包路径。 + /// + string ApplyingResourcePackPath + { + get; + } + + /// + /// 获取等待应用资源数量。 + /// + int ApplyWaitingCount + { + get; + } + + /// + /// 获取或设置资源更新重试次数。 + /// + int UpdateRetryCount + { + get; + set; + } + + /// + /// 获取正在更新的资源组。 + /// + IResourceGroup UpdatingResourceGroup + { + get; + } + + /// + /// 获取等待更新资源数量。 + /// + int UpdateWaitingCount + { + get; + } + + /// + /// 获取使用时下载的等待更新资源数量。 + /// + int UpdateWaitingWhilePlayingCount + { + get; + } + + /// + /// 获取候选更新资源数量。 + /// + int UpdateCandidateCount + { + get; + } + + /// + /// 获取加载资源代理总数量。 + /// + int LoadTotalAgentCount + { + get; + } + + /// + /// 获取可用加载资源代理数量。 + /// + int LoadFreeAgentCount + { + get; + } + + /// + /// 获取工作中加载资源代理数量。 + /// + int LoadWorkingAgentCount + { + get; + } + + /// + /// 获取等待加载资源任务数量。 + /// + int LoadWaitingTaskCount + { + get; + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + float AssetAutoReleaseInterval + { + get; + set; + } + + /// + /// 获取或设置资源对象池的容量。 + /// + int AssetCapacity + { + get; + set; + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + float AssetExpireTime + { + get; + set; + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + int AssetPriority + { + get; + set; + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + float ResourceAutoReleaseInterval + { + get; + set; + } + + /// + /// 获取或设置资源对象池的容量。 + /// + int ResourceCapacity + { + get; + set; + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + float ResourceExpireTime + { + get; + set; + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + int ResourcePriority + { + get; + set; + } + + /// + /// 资源校验开始事件。 + /// + event EventHandler ResourceVerifyStart; + + /// + /// 资源校验成功事件。 + /// + event EventHandler ResourceVerifySuccess; + + /// + /// 资源校验失败事件。 + /// + event EventHandler ResourceVerifyFailure; + + /// + /// 资源应用开始事件。 + /// + event EventHandler ResourceApplyStart; + + /// + /// 资源应用成功事件。 + /// + event EventHandler ResourceApplySuccess; + + /// + /// 资源应用失败事件。 + /// + event EventHandler ResourceApplyFailure; + + /// + /// 资源更新开始事件。 + /// + event EventHandler ResourceUpdateStart; + + /// + /// 资源更新改变事件。 + /// + event EventHandler ResourceUpdateChanged; + + /// + /// 资源更新成功事件。 + /// + event EventHandler ResourceUpdateSuccess; + + /// + /// 资源更新失败事件。 + /// + event EventHandler ResourceUpdateFailure; + + /// + /// 资源更新全部完成事件。 + /// + event EventHandler ResourceUpdateAllComplete; + + /// + /// 设置资源只读区路径。 + /// + /// 资源只读区路径。 + void SetReadOnlyPath(string readOnlyPath); + + /// + /// 设置资源读写区路径。 + /// + /// 资源读写区路径。 + void SetReadWritePath(string readWritePath); + + /// + /// 设置资源模式。 + /// + /// 资源模式。 + void SetResourceMode(ResourceMode resourceMode); + + /// + /// 设置当前变体。 + /// + /// 当前变体。 + void SetCurrentVariant(string currentVariant); + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + void SetObjectPoolManager(IObjectPoolManager objectPoolManager); + + /// + /// 设置文件系统管理器。 + /// + /// 文件系统管理器。 + void SetFileSystemManager(IFileSystemManager fileSystemManager); + + /// + /// 设置下载管理器。 + /// + /// 下载管理器。 + void SetDownloadManager(IDownloadManager downloadManager); + + /// + /// 设置解密资源回调函数。 + /// + /// 要设置的解密资源回调函数。 + /// 如果不设置,将使用默认的解密资源回调函数。 + void SetDecryptResourceCallback(DecryptResourceCallback decryptResourceCallback); + + /// + /// 设置资源辅助器。 + /// + /// 资源辅助器。 + void SetResourceHelper(IResourceHelper resourceHelper); + + /// + /// 增加加载资源代理辅助器。 + /// + /// 要增加的加载资源代理辅助器。 + void AddLoadResourceAgentHelper(ILoadResourceAgentHelper loadResourceAgentHelper); + + /// + /// 使用单机模式并初始化资源。 + /// + /// 使用单机模式并初始化资源完成时的回调函数。 + void InitResources(InitResourcesCompleteCallback initResourcesCompleteCallback); + + /// + /// 使用可更新模式并检查版本资源列表。 + /// + /// 最新的内部资源版本号。 + /// 检查版本资源列表结果。 + CheckVersionListResult CheckVersionList(int latestInternalResourceVersion); + + /// + /// 使用可更新模式并更新版本资源列表。 + /// + /// 版本资源列表大小。 + /// 版本资源列表哈希值。 + /// 版本资源列表压缩后大小。 + /// 版本资源列表压缩后哈希值。 + /// 版本资源列表更新回调函数集。 + void UpdateVersionList(int versionListLength, int versionListHashCode, int versionListCompressedLength, int versionListCompressedHashCode, UpdateVersionListCallbacks updateVersionListCallbacks); + + /// + /// 使用可更新模式并校验资源。 + /// + /// 每帧至少校验资源的大小,以字节为单位。 + /// 使用可更新模式并校验资源完成时的回调函数。 + void VerifyResources(int verifyResourceLengthPerFrame, VerifyResourcesCompleteCallback verifyResourcesCompleteCallback); + + /// + /// 使用可更新模式并检查资源。 + /// + /// 是否忽略处理其它变体的资源,若不忽略,将会移除其它变体的资源。 + /// 使用可更新模式并检查资源完成时的回调函数。 + void CheckResources(bool ignoreOtherVariant, CheckResourcesCompleteCallback checkResourcesCompleteCallback); + + /// + /// 使用可更新模式并应用资源包资源。 + /// + /// 要应用的资源包路径。 + /// 使用可更新模式并应用资源包资源完成时的回调函数。 + void ApplyResources(string resourcePackPath, ApplyResourcesCompleteCallback applyResourcesCompleteCallback); + + /// + /// 使用可更新模式并更新所有资源。 + /// + /// 使用可更新模式并更新默认资源组完成时的回调函数。 + void UpdateResources(UpdateResourcesCompleteCallback updateResourcesCompleteCallback); + + /// + /// 使用可更新模式并更新指定资源组的资源。 + /// + /// 要更新的资源组名称。 + /// 使用可更新模式并更新指定资源组完成时的回调函数。 + void UpdateResources(string resourceGroupName, UpdateResourcesCompleteCallback updateResourcesCompleteCallback); + + /// + /// 停止更新资源。 + /// + void StopUpdateResources(); + + /// + /// 校验资源包。 + /// + /// 要校验的资源包路径。 + /// 是否校验资源包成功。 + bool VerifyResourcePack(string resourcePackPath); + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + TaskInfo[] GetAllLoadAssetInfos(); + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + void GetAllLoadAssetInfos(List results); + + /// + /// 检查资源是否存在。 + /// + /// 要检查资源的名称。 + /// 检查资源是否存在的结果。 + HasAssetResult HasAsset(string assetName); + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源回调函数集。 + void LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks); + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源回调函数集。 + void LoadAsset(string assetName, Type assetType, LoadAssetCallbacks loadAssetCallbacks); + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + void LoadAsset(string assetName, int priority, LoadAssetCallbacks loadAssetCallbacks); + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + void LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks, object userData); + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks); + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + void LoadAsset(string assetName, Type assetType, LoadAssetCallbacks loadAssetCallbacks, object userData); + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + void LoadAsset(string assetName, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData); + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData); + + /// + /// 卸载资源。 + /// + /// 要卸载的资源。 + void UnloadAsset(object asset); + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景回调函数集。 + void LoadScene(string sceneAssetName, LoadSceneCallbacks loadSceneCallbacks); + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景资源的优先级。 + /// 加载场景回调函数集。 + void LoadScene(string sceneAssetName, int priority, LoadSceneCallbacks loadSceneCallbacks); + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景回调函数集。 + /// 用户自定义数据。 + void LoadScene(string sceneAssetName, LoadSceneCallbacks loadSceneCallbacks, object userData); + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景资源的优先级。 + /// 加载场景回调函数集。 + /// 用户自定义数据。 + void LoadScene(string sceneAssetName, int priority, LoadSceneCallbacks loadSceneCallbacks, object userData); + + /// + /// 异步卸载场景。 + /// + /// 要卸载场景资源的名称。 + /// 卸载场景回调函数集。 + void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks); + + /// + /// 异步卸载场景。 + /// + /// 要卸载场景资源的名称。 + /// 卸载场景回调函数集。 + /// 用户自定义数据。 + void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData); + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源的实际路径。 + /// 此方法仅适用于二进制资源存储在磁盘(而非文件系统)中的情况。若二进制资源存储在文件系统中时,返回值将始终为空。 + string GetBinaryPath(string binaryAssetName); + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源是否存储在只读区中。 + /// 二进制资源是否存储在文件系统中。 + /// 二进制资源或存储二进制资源的文件系统,相对于只读区或者读写区的相对路径。 + /// 若二进制资源存储在文件系统中,则指示二进制资源在文件系统中的名称,否则此参数返回空。 + /// 是否获取二进制资源的实际路径成功。 + bool GetBinaryPath(string binaryAssetName, out bool storageInReadOnly, out bool storageInFileSystem, out string relativePath, out string fileName); + + /// + /// 获取二进制资源的长度。 + /// + /// 要获取长度的二进制资源的名称。 + /// 二进制资源的长度。 + int GetBinaryLength(string binaryAssetName); + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks); + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + /// 用户自定义数据。 + void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks, object userData); + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + byte[] LoadBinaryFromFileSystem(string binaryAssetName); + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 实际加载了多少字节。 + int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer); + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 实际加载了多少字节。 + int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex); + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 存储加载二进制资源的二进制流的长度。 + /// 实际加载了多少字节。 + int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length); + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int length); + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, int length); + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 实际加载了多少字节。 + int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer); + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer, int length); + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length); + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 实际加载了多少字节。 + int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer); + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int length); + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int startIndex, int length); + + /// + /// 检查资源组是否存在。 + /// + /// 要检查资源组的名称。 + /// 资源组是否存在。 + bool HasResourceGroup(string resourceGroupName); + + /// + /// 获取默认资源组。 + /// + /// 默认资源组。 + IResourceGroup GetResourceGroup(); + + /// + /// 获取资源组。 + /// + /// 要获取的资源组名称。 + /// 要获取的资源组。 + IResourceGroup GetResourceGroup(string resourceGroupName); + + /// + /// 获取所有资源组。 + /// + /// 所有资源组。 + IResourceGroup[] GetAllResourceGroups(); + + /// + /// 获取所有资源组。 + /// + /// 所有资源组。 + void GetAllResourceGroups(List results); + + /// + /// 获取资源组集合。 + /// + /// 要获取的资源组名称的集合。 + /// 要获取的资源组集合。 + IResourceGroupCollection GetResourceGroupCollection(params string[] resourceGroupNames); + + /// + /// 获取资源组集合。 + /// + /// 要获取的资源组名称的集合。 + /// 要获取的资源组集合。 + IResourceGroupCollection GetResourceGroupCollection(List resourceGroupNames); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceManager.cs.meta new file mode 100644 index 0000000..5a29a4f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/IResourceManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 038760ab28b316644b1791632030d586 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/InitResourcesCompleteCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/InitResourcesCompleteCallback.cs new file mode 100644 index 0000000..e2554f3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/InitResourcesCompleteCallback.cs @@ -0,0 +1,14 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 使用单机模式并初始化资源完成时的回调函数。 + /// + public delegate void InitResourcesCompleteCallback(); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/InitResourcesCompleteCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/InitResourcesCompleteCallback.cs.meta new file mode 100644 index 0000000..4e5cbaf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/InitResourcesCompleteCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9c4e61d606a9af4087fc5a0aa1e305f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetCallbacks.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetCallbacks.cs new file mode 100644 index 0000000..a5015d6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetCallbacks.cs @@ -0,0 +1,145 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源回调函数集。 + /// + public sealed class LoadAssetCallbacks + { + private readonly LoadAssetSuccessCallback m_LoadAssetSuccessCallback; + private readonly LoadAssetFailureCallback m_LoadAssetFailureCallback; + private readonly LoadAssetUpdateCallback m_LoadAssetUpdateCallback; + private readonly LoadAssetDependencyAssetCallback m_LoadAssetDependencyAssetCallback; + + /// + /// 初始化加载资源回调函数集的新实例。 + /// + /// 加载资源成功回调函数。 + public LoadAssetCallbacks(LoadAssetSuccessCallback loadAssetSuccessCallback) + : this(loadAssetSuccessCallback, null, null, null) + { + } + + /// + /// 初始化加载资源回调函数集的新实例。 + /// + /// 加载资源成功回调函数。 + /// 加载资源失败回调函数。 + public LoadAssetCallbacks(LoadAssetSuccessCallback loadAssetSuccessCallback, LoadAssetFailureCallback loadAssetFailureCallback) + : this(loadAssetSuccessCallback, loadAssetFailureCallback, null, null) + { + } + + /// + /// 初始化加载资源回调函数集的新实例。 + /// + /// 加载资源成功回调函数。 + /// 加载资源更新回调函数。 + public LoadAssetCallbacks(LoadAssetSuccessCallback loadAssetSuccessCallback, LoadAssetUpdateCallback loadAssetUpdateCallback) + : this(loadAssetSuccessCallback, null, loadAssetUpdateCallback, null) + { + } + + /// + /// 初始化加载资源回调函数集的新实例。 + /// + /// 加载资源成功回调函数。 + /// 加载资源时加载依赖资源回调函数。 + public LoadAssetCallbacks(LoadAssetSuccessCallback loadAssetSuccessCallback, LoadAssetDependencyAssetCallback loadAssetDependencyAssetCallback) + : this(loadAssetSuccessCallback, null, null, loadAssetDependencyAssetCallback) + { + } + + /// + /// 初始化加载资源回调函数集的新实例。 + /// + /// 加载资源成功回调函数。 + /// 加载资源失败回调函数。 + /// 加载资源更新回调函数。 + public LoadAssetCallbacks(LoadAssetSuccessCallback loadAssetSuccessCallback, LoadAssetFailureCallback loadAssetFailureCallback, LoadAssetUpdateCallback loadAssetUpdateCallback) + : this(loadAssetSuccessCallback, loadAssetFailureCallback, loadAssetUpdateCallback, null) + { + } + + /// + /// 初始化加载资源回调函数集的新实例。 + /// + /// 加载资源成功回调函数。 + /// 加载资源失败回调函数。 + /// 加载资源时加载依赖资源回调函数。 + public LoadAssetCallbacks(LoadAssetSuccessCallback loadAssetSuccessCallback, LoadAssetFailureCallback loadAssetFailureCallback, LoadAssetDependencyAssetCallback loadAssetDependencyAssetCallback) + : this(loadAssetSuccessCallback, loadAssetFailureCallback, null, loadAssetDependencyAssetCallback) + { + } + + /// + /// 初始化加载资源回调函数集的新实例。 + /// + /// 加载资源成功回调函数。 + /// 加载资源失败回调函数。 + /// 加载资源更新回调函数。 + /// 加载资源时加载依赖资源回调函数。 + public LoadAssetCallbacks(LoadAssetSuccessCallback loadAssetSuccessCallback, LoadAssetFailureCallback loadAssetFailureCallback, LoadAssetUpdateCallback loadAssetUpdateCallback, LoadAssetDependencyAssetCallback loadAssetDependencyAssetCallback) + { + if (loadAssetSuccessCallback == null) + { + throw new GameFrameworkException("Load asset success callback is invalid."); + } + + m_LoadAssetSuccessCallback = loadAssetSuccessCallback; + m_LoadAssetFailureCallback = loadAssetFailureCallback; + m_LoadAssetUpdateCallback = loadAssetUpdateCallback; + m_LoadAssetDependencyAssetCallback = loadAssetDependencyAssetCallback; + } + + /// + /// 获取加载资源成功回调函数。 + /// + public LoadAssetSuccessCallback LoadAssetSuccessCallback + { + get + { + return m_LoadAssetSuccessCallback; + } + } + + /// + /// 获取加载资源失败回调函数。 + /// + public LoadAssetFailureCallback LoadAssetFailureCallback + { + get + { + return m_LoadAssetFailureCallback; + } + } + + /// + /// 获取加载资源更新回调函数。 + /// + public LoadAssetUpdateCallback LoadAssetUpdateCallback + { + get + { + return m_LoadAssetUpdateCallback; + } + } + + /// + /// 获取加载资源时加载依赖资源回调函数。 + /// + public LoadAssetDependencyAssetCallback LoadAssetDependencyAssetCallback + { + get + { + return m_LoadAssetDependencyAssetCallback; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetCallbacks.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetCallbacks.cs.meta new file mode 100644 index 0000000..5ba0ef5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4652225d9b1288b4a89731266c2449b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetDependencyAssetCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetDependencyAssetCallback.cs new file mode 100644 index 0000000..d27644f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetDependencyAssetCallback.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源时加载依赖资源回调函数。 + /// + /// 要加载的资源名称。 + /// 被加载的依赖资源名称。 + /// 当前已加载依赖资源数量。 + /// 总共加载依赖资源数量。 + /// 用户自定义数据。 + public delegate void LoadAssetDependencyAssetCallback(string assetName, string dependencyAssetName, int loadedCount, int totalCount, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetDependencyAssetCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetDependencyAssetCallback.cs.meta new file mode 100644 index 0000000..ead2a06 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetDependencyAssetCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0922e8a04dfc4c74ab36c5761b282458 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetFailureCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetFailureCallback.cs new file mode 100644 index 0000000..6bbf320 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetFailureCallback.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源失败回调函数。 + /// + /// 要加载的资源名称。 + /// 加载资源状态。 + /// 错误信息。 + /// 用户自定义数据。 + public delegate void LoadAssetFailureCallback(string assetName, LoadResourceStatus status, string errorMessage, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetFailureCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetFailureCallback.cs.meta new file mode 100644 index 0000000..2e83768 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetFailureCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1bbb5bf5a296c714fbb1e5ec319ab75d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetSuccessCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetSuccessCallback.cs new file mode 100644 index 0000000..42e1e2b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetSuccessCallback.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源成功回调函数。 + /// + /// 要加载的资源名称。 + /// 已加载的资源。 + /// 加载持续时间。 + /// 用户自定义数据。 + public delegate void LoadAssetSuccessCallback(string assetName, object asset, float duration, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetSuccessCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetSuccessCallback.cs.meta new file mode 100644 index 0000000..11b3ddf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetSuccessCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 525f9ed1013d56a4c803f50014a31798 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetUpdateCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetUpdateCallback.cs new file mode 100644 index 0000000..c974418 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetUpdateCallback.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源更新回调函数。 + /// + /// 要加载的资源名称。 + /// 加载资源进度。 + /// 用户自定义数据。 + public delegate void LoadAssetUpdateCallback(string assetName, float progress, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetUpdateCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetUpdateCallback.cs.meta new file mode 100644 index 0000000..3254e80 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadAssetUpdateCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f013846d09e1cc3459459323f413f7a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryCallbacks.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryCallbacks.cs new file mode 100644 index 0000000..6f48103 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryCallbacks.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载二进制资源回调函数集。 + /// + public sealed class LoadBinaryCallbacks + { + private readonly LoadBinarySuccessCallback m_LoadBinarySuccessCallback; + private readonly LoadBinaryFailureCallback m_LoadBinaryFailureCallback; + + /// + /// 初始化加载二进制资源回调函数集的新实例。 + /// + /// 加载二进制资源成功回调函数。 + public LoadBinaryCallbacks(LoadBinarySuccessCallback loadBinarySuccessCallback) + : this(loadBinarySuccessCallback, null) + { + } + + /// + /// 初始化加载二进制资源回调函数集的新实例。 + /// + /// 加载二进制资源成功回调函数。 + /// 加载二进制资源失败回调函数。 + public LoadBinaryCallbacks(LoadBinarySuccessCallback loadBinarySuccessCallback, LoadBinaryFailureCallback loadBinaryFailureCallback) + { + if (loadBinarySuccessCallback == null) + { + throw new GameFrameworkException("Load binary success callback is invalid."); + } + + m_LoadBinarySuccessCallback = loadBinarySuccessCallback; + m_LoadBinaryFailureCallback = loadBinaryFailureCallback; + } + + /// + /// 获取加载二进制资源成功回调函数。 + /// + public LoadBinarySuccessCallback LoadBinarySuccessCallback + { + get + { + return m_LoadBinarySuccessCallback; + } + } + + /// + /// 获取加载二进制资源失败回调函数。 + /// + public LoadBinaryFailureCallback LoadBinaryFailureCallback + { + get + { + return m_LoadBinaryFailureCallback; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryCallbacks.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryCallbacks.cs.meta new file mode 100644 index 0000000..b31ddbb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d93de184ed0e7994890f43c306afacc1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryFailureCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryFailureCallback.cs new file mode 100644 index 0000000..b082502 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryFailureCallback.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载二进制资源失败回调函数。 + /// + /// 要加载的二进制资源名称。 + /// 加载二进制资源状态。 + /// 错误信息。 + /// 用户自定义数据。 + public delegate void LoadBinaryFailureCallback(string binaryAssetName, LoadResourceStatus status, string errorMessage, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryFailureCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryFailureCallback.cs.meta new file mode 100644 index 0000000..8a20c3d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinaryFailureCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bcc38546a41000f4f8793fc9e7641920 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinarySuccessCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinarySuccessCallback.cs new file mode 100644 index 0000000..d6c9476 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinarySuccessCallback.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载二进制资源成功回调函数。 + /// + /// 要加载的二进制资源名称。 + /// 已加载的二进制资源。 + /// 加载持续时间。 + /// 用户自定义数据。 + public delegate void LoadBinarySuccessCallback(string binaryAssetName, byte[] binaryBytes, float duration, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinarySuccessCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinarySuccessCallback.cs.meta new file mode 100644 index 0000000..8cf5290 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBinarySuccessCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc3d41c2d26b7fb4bb704cdbf76cf614 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesCallbacks.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesCallbacks.cs new file mode 100644 index 0000000..0e371b3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesCallbacks.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载数据流回调函数集。 + /// + public sealed class LoadBytesCallbacks + { + private readonly LoadBytesSuccessCallback m_LoadBytesSuccessCallback; + private readonly LoadBytesFailureCallback m_LoadBytesFailureCallback; + + /// + /// 初始化加载数据流回调函数集的新实例。 + /// + /// 加载数据流成功回调函数。 + public LoadBytesCallbacks(LoadBytesSuccessCallback loadBinarySuccessCallback) + : this(loadBinarySuccessCallback, null) + { + } + + /// + /// 初始化加载数据流回调函数集的新实例。 + /// + /// 加载数据流成功回调函数。 + /// 加载数据流失败回调函数。 + public LoadBytesCallbacks(LoadBytesSuccessCallback loadBytesSuccessCallback, LoadBytesFailureCallback loadBytesFailureCallback) + { + if (loadBytesSuccessCallback == null) + { + throw new GameFrameworkException("Load bytes success callback is invalid."); + } + + m_LoadBytesSuccessCallback = loadBytesSuccessCallback; + m_LoadBytesFailureCallback = loadBytesFailureCallback; + } + + /// + /// 获取加载数据流成功回调函数。 + /// + public LoadBytesSuccessCallback LoadBytesSuccessCallback + { + get + { + return m_LoadBytesSuccessCallback; + } + } + + /// + /// 获取加载数据流失败回调函数。 + /// + public LoadBytesFailureCallback LoadBytesFailureCallback + { + get + { + return m_LoadBytesFailureCallback; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesCallbacks.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesCallbacks.cs.meta new file mode 100644 index 0000000..4260c1a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6856785609b439b48b21edb6d85a8f0a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesFailureCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesFailureCallback.cs new file mode 100644 index 0000000..9195bf0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesFailureCallback.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载数据流失败回调函数。 + /// + /// 文件路径。 + /// 错误信息。 + /// 用户自定义数据。 + public delegate void LoadBytesFailureCallback(string fileUri, string errorMessage, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesFailureCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesFailureCallback.cs.meta new file mode 100644 index 0000000..c89bbed --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesFailureCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f161856940cb63340805028f4a59c78d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesSuccessCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesSuccessCallback.cs new file mode 100644 index 0000000..538a67b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesSuccessCallback.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载数据流成功回调函数。 + /// + /// 文件路径。 + /// 数据流。 + /// 加载持续时间。 + /// 用户自定义数据。 + public delegate void LoadBytesSuccessCallback(string fileUri, byte[] bytes, float duration, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesSuccessCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesSuccessCallback.cs.meta new file mode 100644 index 0000000..7292201 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadBytesSuccessCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ccbac9811cf09cb4aa2df8e072fc371e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperErrorEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperErrorEventArgs.cs new file mode 100644 index 0000000..d6b7e7c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperErrorEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源代理辅助器错误事件。 + /// + public sealed class LoadResourceAgentHelperErrorEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载资源代理辅助器错误事件的新实例。 + /// + public LoadResourceAgentHelperErrorEventArgs() + { + Status = LoadResourceStatus.Success; + ErrorMessage = null; + } + + /// + /// 获取加载资源状态。 + /// + public LoadResourceStatus Status + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建加载资源代理辅助器错误事件。 + /// + /// 加载资源状态。 + /// 错误信息。 + /// 创建的加载资源代理辅助器错误事件。 + public static LoadResourceAgentHelperErrorEventArgs Create(LoadResourceStatus status, string errorMessage) + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = ReferencePool.Acquire(); + loadResourceAgentHelperErrorEventArgs.Status = status; + loadResourceAgentHelperErrorEventArgs.ErrorMessage = errorMessage; + return loadResourceAgentHelperErrorEventArgs; + } + + /// + /// 清理加载资源代理辅助器错误事件。 + /// + public override void Clear() + { + Status = LoadResourceStatus.Success; + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperErrorEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperErrorEventArgs.cs.meta new file mode 100644 index 0000000..3687f79 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperErrorEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 279209080a115674681468071d5a31e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperLoadCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperLoadCompleteEventArgs.cs new file mode 100644 index 0000000..24fbeaa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperLoadCompleteEventArgs.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源代理辅助器异步加载资源完成事件。 + /// + public sealed class LoadResourceAgentHelperLoadCompleteEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载资源代理辅助器异步加载资源完成事件的新实例。 + /// + public LoadResourceAgentHelperLoadCompleteEventArgs() + { + Asset = null; + } + + /// + /// 获取加载的资源。 + /// + public object Asset + { + get; + private set; + } + + /// + /// 创建加载资源代理辅助器异步加载资源完成事件。 + /// + /// 加载的资源。 + /// 创建的加载资源代理辅助器异步加载资源完成事件。 + public static LoadResourceAgentHelperLoadCompleteEventArgs Create(object asset) + { + LoadResourceAgentHelperLoadCompleteEventArgs loadResourceAgentHelperLoadCompleteEventArgs = ReferencePool.Acquire(); + loadResourceAgentHelperLoadCompleteEventArgs.Asset = asset; + return loadResourceAgentHelperLoadCompleteEventArgs; + } + + /// + /// 清理加载资源代理辅助器异步加载资源完成事件。 + /// + public override void Clear() + { + Asset = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperLoadCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperLoadCompleteEventArgs.cs.meta new file mode 100644 index 0000000..9f36f63 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperLoadCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 098adbe9573d6c94bbf666d9e6e9d84b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperParseBytesCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperParseBytesCompleteEventArgs.cs new file mode 100644 index 0000000..c63d693 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperParseBytesCompleteEventArgs.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源代理辅助器异步将资源二进制流转换为加载对象完成事件。 + /// + public sealed class LoadResourceAgentHelperParseBytesCompleteEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载资源代理辅助器异步将资源二进制流转换为加载对象完成事件的新实例。 + /// + public LoadResourceAgentHelperParseBytesCompleteEventArgs() + { + Resource = null; + } + + /// + /// 获取加载对象。 + /// + public object Resource + { + get; + private set; + } + + /// + /// 创建加载资源代理辅助器异步将资源二进制流转换为加载对象完成事件。 + /// + /// 资源对象。 + /// 创建的加载资源代理辅助器异步将资源二进制流转换为加载对象完成事件。 + public static LoadResourceAgentHelperParseBytesCompleteEventArgs Create(object resource) + { + LoadResourceAgentHelperParseBytesCompleteEventArgs loadResourceAgentHelperParseBytesCompleteEventArgs = ReferencePool.Acquire(); + loadResourceAgentHelperParseBytesCompleteEventArgs.Resource = resource; + return loadResourceAgentHelperParseBytesCompleteEventArgs; + } + + /// + /// 清理加载资源代理辅助器异步将资源二进制流转换为加载对象完成事件。 + /// + public override void Clear() + { + Resource = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperParseBytesCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperParseBytesCompleteEventArgs.cs.meta new file mode 100644 index 0000000..cad4369 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperParseBytesCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da3b1484d29aed049aeddfcba31917d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadBytesCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadBytesCompleteEventArgs.cs new file mode 100644 index 0000000..2dbec52 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadBytesCompleteEventArgs.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源代理辅助器异步读取资源二进制流完成事件。 + /// + public sealed class LoadResourceAgentHelperReadBytesCompleteEventArgs : GameFrameworkEventArgs + { + private byte[] m_Bytes; + + /// + /// 初始化加载资源代理辅助器异步读取资源二进制流完成事件的新实例。 + /// + public LoadResourceAgentHelperReadBytesCompleteEventArgs() + { + m_Bytes = null; + } + + /// + /// 创建加载资源代理辅助器异步读取资源二进制流完成事件。 + /// + /// 资源的二进制流。 + /// 创建的加载资源代理辅助器异步读取资源二进制流完成事件。 + public static LoadResourceAgentHelperReadBytesCompleteEventArgs Create(byte[] bytes) + { + LoadResourceAgentHelperReadBytesCompleteEventArgs loadResourceAgentHelperReadBytesCompleteEventArgs = ReferencePool.Acquire(); + loadResourceAgentHelperReadBytesCompleteEventArgs.m_Bytes = bytes; + return loadResourceAgentHelperReadBytesCompleteEventArgs; + } + + /// + /// 清理加载资源代理辅助器异步读取资源二进制流完成事件。 + /// + public override void Clear() + { + m_Bytes = null; + } + + /// + /// 获取资源的二进制流。 + /// + /// 资源的二进制流。 + public byte[] GetBytes() + { + return m_Bytes; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadBytesCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadBytesCompleteEventArgs.cs.meta new file mode 100644 index 0000000..32060ad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadBytesCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5ae5dfbc2092c24194accb67b04a534 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadFileCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadFileCompleteEventArgs.cs new file mode 100644 index 0000000..62c39ee --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadFileCompleteEventArgs.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源代理辅助器异步将资源文件转换为加载对象完成事件。 + /// + public sealed class LoadResourceAgentHelperReadFileCompleteEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载资源代理辅助器异步将资源文件转换为加载对象完成事件的新实例。 + /// + public LoadResourceAgentHelperReadFileCompleteEventArgs() + { + Resource = null; + } + + /// + /// 获取加载对象。 + /// + public object Resource + { + get; + private set; + } + + /// + /// 创建加载资源代理辅助器异步将资源文件转换为加载对象完成事件。 + /// + /// 资源对象。 + /// 创建的加载资源代理辅助器异步将资源文件转换为加载对象完成事件。 + public static LoadResourceAgentHelperReadFileCompleteEventArgs Create(object resource) + { + LoadResourceAgentHelperReadFileCompleteEventArgs loadResourceAgentHelperReadFileCompleteEventArgs = ReferencePool.Acquire(); + loadResourceAgentHelperReadFileCompleteEventArgs.Resource = resource; + return loadResourceAgentHelperReadFileCompleteEventArgs; + } + + /// + /// 清理加载资源代理辅助器异步将资源文件转换为加载对象完成事件。 + /// + public override void Clear() + { + Resource = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadFileCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadFileCompleteEventArgs.cs.meta new file mode 100644 index 0000000..fe54932 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperReadFileCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5b241a15eaa2cc44944bb30e9d06c24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperUpdateEventArgs.cs new file mode 100644 index 0000000..fded812 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperUpdateEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源代理辅助器更新事件。 + /// + public sealed class LoadResourceAgentHelperUpdateEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载资源代理辅助器更新事件的新实例。 + /// + public LoadResourceAgentHelperUpdateEventArgs() + { + Type = LoadResourceProgress.Unknown; + Progress = 0f; + } + + /// + /// 获取进度类型。 + /// + public LoadResourceProgress Type + { + get; + private set; + } + + /// + /// 获取进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 创建加载资源代理辅助器更新事件。 + /// + /// 进度类型。 + /// 进度。 + /// 创建的加载资源代理辅助器更新事件。 + public static LoadResourceAgentHelperUpdateEventArgs Create(LoadResourceProgress type, float progress) + { + LoadResourceAgentHelperUpdateEventArgs loadResourceAgentHelperUpdateEventArgs = ReferencePool.Acquire(); + loadResourceAgentHelperUpdateEventArgs.Type = type; + loadResourceAgentHelperUpdateEventArgs.Progress = progress; + return loadResourceAgentHelperUpdateEventArgs; + } + + /// + /// 清理加载资源代理辅助器更新事件。 + /// + public override void Clear() + { + Type = LoadResourceProgress.Unknown; + Progress = 0f; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperUpdateEventArgs.cs.meta new file mode 100644 index 0000000..e94c220 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceAgentHelperUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e1510cd059e5a546b322c507ea78e46 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceProgress.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceProgress.cs new file mode 100644 index 0000000..6293362 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceProgress.cs @@ -0,0 +1,40 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源进度类型。 + /// + public enum LoadResourceProgress : byte + { + /// + /// 未知类型。 + /// + Unknown = 0, + + /// + /// 读取资源包。 + /// + ReadResource, + + /// + /// 加载资源包。 + /// + LoadResource, + + /// + /// 加载资源。 + /// + LoadAsset, + + /// + /// 加载场景。 + /// + LoadScene + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceProgress.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceProgress.cs.meta new file mode 100644 index 0000000..223acb6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceProgress.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1c2d2946a51a6947acb02068cc6405e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceStatus.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceStatus.cs new file mode 100644 index 0000000..ec8d2cc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceStatus.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载资源状态。 + /// + public enum LoadResourceStatus : byte + { + /// + /// 加载资源完成。 + /// + Success = 0, + + /// + /// 资源不存在。 + /// + NotExist, + + /// + /// 资源尚未准备完毕。 + /// + NotReady, + + /// + /// 依赖资源错误。 + /// + DependencyError, + + /// + /// 资源类型错误。 + /// + TypeError, + + /// + /// 加载资源错误。 + /// + AssetError + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceStatus.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceStatus.cs.meta new file mode 100644 index 0000000..c298ad8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadResourceStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7789b800ae94a24e85b3a0b8f1960e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneCallbacks.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneCallbacks.cs new file mode 100644 index 0000000..bbccf88 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneCallbacks.cs @@ -0,0 +1,145 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载场景回调函数集。 + /// + public sealed class LoadSceneCallbacks + { + private readonly LoadSceneSuccessCallback m_LoadSceneSuccessCallback; + private readonly LoadSceneFailureCallback m_LoadSceneFailureCallback; + private readonly LoadSceneUpdateCallback m_LoadSceneUpdateCallback; + private readonly LoadSceneDependencyAssetCallback m_LoadSceneDependencyAssetCallback; + + /// + /// 初始化加载场景回调函数集的新实例。 + /// + /// 加载场景成功回调函数。 + public LoadSceneCallbacks(LoadSceneSuccessCallback loadSceneSuccessCallback) + : this(loadSceneSuccessCallback, null, null, null) + { + } + + /// + /// 初始化加载场景回调函数集的新实例。 + /// + /// 加载场景成功回调函数。 + /// 加载场景失败回调函数。 + public LoadSceneCallbacks(LoadSceneSuccessCallback loadSceneSuccessCallback, LoadSceneFailureCallback loadSceneFailureCallback) + : this(loadSceneSuccessCallback, loadSceneFailureCallback, null, null) + { + } + + /// + /// 初始化加载场景回调函数集的新实例。 + /// + /// 加载场景成功回调函数。 + /// 加载场景更新回调函数。 + public LoadSceneCallbacks(LoadSceneSuccessCallback loadSceneSuccessCallback, LoadSceneUpdateCallback loadSceneUpdateCallback) + : this(loadSceneSuccessCallback, null, loadSceneUpdateCallback, null) + { + } + + /// + /// 初始化加载场景回调函数集的新实例。 + /// + /// 加载场景成功回调函数。 + /// 加载场景时加载依赖资源回调函数。 + public LoadSceneCallbacks(LoadSceneSuccessCallback loadSceneSuccessCallback, LoadSceneDependencyAssetCallback loadSceneDependencyAssetCallback) + : this(loadSceneSuccessCallback, null, null, loadSceneDependencyAssetCallback) + { + } + + /// + /// 初始化加载场景回调函数集的新实例。 + /// + /// 加载场景成功回调函数。 + /// 加载场景失败回调函数。 + /// 加载场景更新回调函数。 + public LoadSceneCallbacks(LoadSceneSuccessCallback loadSceneSuccessCallback, LoadSceneFailureCallback loadSceneFailureCallback, LoadSceneUpdateCallback loadSceneUpdateCallback) + : this(loadSceneSuccessCallback, loadSceneFailureCallback, loadSceneUpdateCallback, null) + { + } + + /// + /// 初始化加载场景回调函数集的新实例。 + /// + /// 加载场景成功回调函数。 + /// 加载场景失败回调函数。 + /// 加载场景时加载依赖资源回调函数。 + public LoadSceneCallbacks(LoadSceneSuccessCallback loadSceneSuccessCallback, LoadSceneFailureCallback loadSceneFailureCallback, LoadSceneDependencyAssetCallback loadSceneDependencyAssetCallback) + : this(loadSceneSuccessCallback, loadSceneFailureCallback, null, loadSceneDependencyAssetCallback) + { + } + + /// + /// 初始化加载场景回调函数集的新实例。 + /// + /// 加载场景成功回调函数。 + /// 加载场景失败回调函数。 + /// 加载场景更新回调函数。 + /// 加载场景时加载依赖资源回调函数。 + public LoadSceneCallbacks(LoadSceneSuccessCallback loadSceneSuccessCallback, LoadSceneFailureCallback loadSceneFailureCallback, LoadSceneUpdateCallback loadSceneUpdateCallback, LoadSceneDependencyAssetCallback loadSceneDependencyAssetCallback) + { + if (loadSceneSuccessCallback == null) + { + throw new GameFrameworkException("Load scene success callback is invalid."); + } + + m_LoadSceneSuccessCallback = loadSceneSuccessCallback; + m_LoadSceneFailureCallback = loadSceneFailureCallback; + m_LoadSceneUpdateCallback = loadSceneUpdateCallback; + m_LoadSceneDependencyAssetCallback = loadSceneDependencyAssetCallback; + } + + /// + /// 获取加载场景成功回调函数。 + /// + public LoadSceneSuccessCallback LoadSceneSuccessCallback + { + get + { + return m_LoadSceneSuccessCallback; + } + } + + /// + /// 获取加载场景失败回调函数。 + /// + public LoadSceneFailureCallback LoadSceneFailureCallback + { + get + { + return m_LoadSceneFailureCallback; + } + } + + /// + /// 获取加载场景更新回调函数。 + /// + public LoadSceneUpdateCallback LoadSceneUpdateCallback + { + get + { + return m_LoadSceneUpdateCallback; + } + } + + /// + /// 获取加载场景时加载依赖资源回调函数。 + /// + public LoadSceneDependencyAssetCallback LoadSceneDependencyAssetCallback + { + get + { + return m_LoadSceneDependencyAssetCallback; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneCallbacks.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneCallbacks.cs.meta new file mode 100644 index 0000000..77ff4f1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5525ac1816e1f1845aabe4f837b1ff50 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneDependencyAssetCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneDependencyAssetCallback.cs new file mode 100644 index 0000000..17787a6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneDependencyAssetCallback.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载场景时加载依赖资源回调函数。 + /// + /// 要加载的场景资源名称。 + /// 被加载的依赖资源名称。 + /// 当前已加载依赖资源数量。 + /// 总共加载依赖资源数量。 + /// 用户自定义数据。 + public delegate void LoadSceneDependencyAssetCallback(string sceneAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneDependencyAssetCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneDependencyAssetCallback.cs.meta new file mode 100644 index 0000000..8a2099f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneDependencyAssetCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 023c8a7245911b24696233abe6371d2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneFailureCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneFailureCallback.cs new file mode 100644 index 0000000..4618031 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneFailureCallback.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载场景失败回调函数。 + /// + /// 要加载的场景资源名称。 + /// 加载场景状态。 + /// 错误信息。 + /// 用户自定义数据。 + public delegate void LoadSceneFailureCallback(string sceneAssetName, LoadResourceStatus status, string errorMessage, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneFailureCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneFailureCallback.cs.meta new file mode 100644 index 0000000..5eccdf6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneFailureCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9077a5c3d364bea418216f6f09655127 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneSuccessCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneSuccessCallback.cs new file mode 100644 index 0000000..3fefc8a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneSuccessCallback.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载场景成功回调函数。 + /// + /// 要加载的场景资源名称。 + /// 加载持续时间。 + /// 用户自定义数据。 + public delegate void LoadSceneSuccessCallback(string sceneAssetName, float duration, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneSuccessCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneSuccessCallback.cs.meta new file mode 100644 index 0000000..712808f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneSuccessCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d21d00ba1a130f49b33e4b598417355 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneUpdateCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneUpdateCallback.cs new file mode 100644 index 0000000..bfd5d7c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneUpdateCallback.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 加载场景更新回调函数。 + /// + /// 要加载的场景资源名称。 + /// 加载场景进度。 + /// 用户自定义数据。 + public delegate void LoadSceneUpdateCallback(string sceneAssetName, float progress, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneUpdateCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneUpdateCallback.cs.meta new file mode 100644 index 0000000..742141d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LoadSceneUpdateCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ca48f93df40e6d45933f817943298d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.FileSystem.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.FileSystem.cs new file mode 100644 index 0000000..7052cd0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.FileSystem.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct LocalVersionList + { + /// + /// 文件系统。 + /// + [StructLayout(LayoutKind.Auto)] + public struct FileSystem + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly int[] m_ResourceIndexes; + + /// + /// 初始化文件系统的新实例。 + /// + /// 文件系统名称。 + /// 文件系统包含的资源索引集合。 + public FileSystem(string name, int[] resourceIndexes) + { + if (name == null) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_ResourceIndexes = resourceIndexes ?? EmptyIntArray; + } + + /// + /// 获取文件系统名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取文件系统包含的资源索引集合。 + /// + /// 文件系统包含的资源索引集合。 + public int[] GetResourceIndexes() + { + return m_ResourceIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.FileSystem.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.FileSystem.cs.meta new file mode 100644 index 0000000..da33378 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.FileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab4b9fefcd410fc4995cb00de14dfc2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.Resource.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.Resource.cs new file mode 100644 index 0000000..945ebb7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.Resource.cs @@ -0,0 +1,118 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct LocalVersionList + { + /// + /// 资源。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Resource + { + private readonly string m_Name; + private readonly string m_Variant; + private readonly string m_Extension; + private readonly byte m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + + /// + /// 初始化资源的新实例。 + /// + /// 资源名称。 + /// 资源变体名称。 + /// 资源扩展名称。 + /// 资源加载方式。 + /// 资源长度。 + /// 资源哈希值。 + public Resource(string name, string variant, string extension, byte loadType, int length, int hashCode) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_Variant = variant; + m_Extension = extension; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源变体名称。 + /// + public string Variant + { + get + { + return m_Variant; + } + } + + /// + /// 获取资源扩展名称。 + /// + public string Extension + { + get + { + return m_Extension; + } + } + + /// + /// 获取资源加载方式。 + /// + public byte LoadType + { + get + { + return m_LoadType; + } + } + + /// + /// 获取资源长度。 + /// + public int Length + { + get + { + return m_Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_HashCode; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.Resource.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.Resource.cs.meta new file mode 100644 index 0000000..9a13f24 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.Resource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3088ab3f3ff38df41a91100ec56a4c1b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.cs new file mode 100644 index 0000000..bfeafbc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.cs @@ -0,0 +1,76 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + /// + /// 本地版本资源列表。 + /// + [StructLayout(LayoutKind.Auto)] + public partial struct LocalVersionList + { + private static readonly Resource[] EmptyResourceArray = new Resource[] { }; + private static readonly FileSystem[] EmptyFileSystemArray = new FileSystem[] { }; + + private readonly bool m_IsValid; + private readonly Resource[] m_Resources; + private readonly FileSystem[] m_FileSystems; + + /// + /// 初始化本地版本资源列表的新实例。 + /// + /// 包含的资源集合。 + /// 包含的文件系统集合。 + public LocalVersionList(Resource[] resources, FileSystem[] fileSystems) + { + m_IsValid = true; + m_Resources = resources ?? EmptyResourceArray; + m_FileSystems = fileSystems ?? EmptyFileSystemArray; + } + + /// + /// 获取本地版本资源列表是否有效。 + /// + public bool IsValid + { + get + { + return m_IsValid; + } + } + + /// + /// 获取包含的资源集合。 + /// + /// 包含的资源集合。 + public Resource[] GetResources() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Resources; + } + + /// + /// 获取包含的文件系统集合。 + /// + /// 包含的文件系统集合。 + public FileSystem[] GetFileSystems() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_FileSystems; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.cs.meta new file mode 100644 index 0000000..789e429 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/LocalVersionList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 96f54073a71bbd84ebe6a4bb2d652a05 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Asset.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Asset.cs new file mode 100644 index 0000000..2f35aa6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Asset.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct PackageVersionList + { + /// + /// 资源。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Asset + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly int[] m_DependencyAssetIndexes; + + /// + /// 初始化资源的新实例。 + /// + /// 资源名称。 + /// 资源包含的依赖资源索引集合。 + public Asset(string name, int[] dependencyAssetIndexes) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_DependencyAssetIndexes = dependencyAssetIndexes ?? EmptyIntArray; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源包含的依赖资源索引集合。 + /// + /// 资源包含的依赖资源索引集合。 + public int[] GetDependencyAssetIndexes() + { + return m_DependencyAssetIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Asset.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Asset.cs.meta new file mode 100644 index 0000000..6fd166b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Asset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c9e5247d2b8c234fb66e6c11d249ca6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.FileSystem.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.FileSystem.cs new file mode 100644 index 0000000..25e577c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.FileSystem.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct PackageVersionList + { + /// + /// 文件系统。 + /// + [StructLayout(LayoutKind.Auto)] + public struct FileSystem + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly int[] m_ResourceIndexes; + + /// + /// 初始化文件系统的新实例。 + /// + /// 文件系统名称。 + /// 文件系统包含的资源索引集合。 + public FileSystem(string name, int[] resourceIndexes) + { + if (name == null) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_ResourceIndexes = resourceIndexes ?? EmptyIntArray; + } + + /// + /// 获取文件系统名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取文件系统包含的资源索引集合。 + /// + /// 文件系统包含的资源索引集合。 + public int[] GetResourceIndexes() + { + return m_ResourceIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.FileSystem.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.FileSystem.cs.meta new file mode 100644 index 0000000..9f5eac1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.FileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 005ba6014d1d6b84a96404980a310779 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Resource.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Resource.cs new file mode 100644 index 0000000..e2f7beb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Resource.cs @@ -0,0 +1,132 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct PackageVersionList + { + /// + /// 资源。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Resource + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly string m_Variant; + private readonly string m_Extension; + private readonly byte m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly int[] m_AssetIndexes; + + /// + /// 初始化资源的新实例。 + /// + /// 资源名称。 + /// 资源变体名称。 + /// 资源扩展名称。 + /// 资源加载方式。 + /// 资源长度。 + /// 资源哈希值。 + /// 资源包含的资源索引集合。 + public Resource(string name, string variant, string extension, byte loadType, int length, int hashCode, int[] assetIndexes) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_Variant = variant; + m_Extension = extension; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + m_AssetIndexes = assetIndexes ?? EmptyIntArray; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源变体名称。 + /// + public string Variant + { + get + { + return m_Variant; + } + } + + /// + /// 获取资源扩展名称。 + /// + public string Extension + { + get + { + return m_Extension; + } + } + + /// + /// 获取资源加载方式。 + /// + public byte LoadType + { + get + { + return m_LoadType; + } + } + + /// + /// 获取资源长度。 + /// + public int Length + { + get + { + return m_Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_HashCode; + } + } + + /// + /// 获取资源包含的资源索引集合。 + /// + /// 资源包含的资源索引集合。 + public int[] GetAssetIndexes() + { + return m_AssetIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Resource.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Resource.cs.meta new file mode 100644 index 0000000..3df6bab --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.Resource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f3089363b160d74ea1a59e500eef66a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.ResourceGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.ResourceGroup.cs new file mode 100644 index 0000000..630ba68 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.ResourceGroup.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct PackageVersionList + { + /// + /// 资源组。 + /// + [StructLayout(LayoutKind.Auto)] + public struct ResourceGroup + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly int[] m_ResourceIndexes; + + /// + /// 初始化资源组的新实例。 + /// + /// 资源组名称。 + /// 资源组包含的资源索引集合。 + public ResourceGroup(string name, int[] resourceIndexes) + { + if (name == null) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_ResourceIndexes = resourceIndexes ?? EmptyIntArray; + } + + /// + /// 获取资源组名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源组包含的资源索引集合。 + /// + /// 资源组包含的资源索引集合。 + public int[] GetResourceIndexes() + { + return m_ResourceIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.ResourceGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.ResourceGroup.cs.meta new file mode 100644 index 0000000..27f9e73 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.ResourceGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 231ad5750b30fa340a72cb89f9911e4e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.cs new file mode 100644 index 0000000..cb1fca5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.cs @@ -0,0 +1,150 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + /// + /// 单机模式版本资源列表。 + /// + [StructLayout(LayoutKind.Auto)] + public partial struct PackageVersionList + { + private static readonly Asset[] EmptyAssetArray = new Asset[] { }; + private static readonly Resource[] EmptyResourceArray = new Resource[] { }; + private static readonly FileSystem[] EmptyFileSystemArray = new FileSystem[] { }; + private static readonly ResourceGroup[] EmptyResourceGroupArray = new ResourceGroup[] { }; + + private readonly bool m_IsValid; + private readonly string m_ApplicableGameVersion; + private readonly int m_InternalResourceVersion; + private readonly Asset[] m_Assets; + private readonly Resource[] m_Resources; + private readonly FileSystem[] m_FileSystems; + private readonly ResourceGroup[] m_ResourceGroups; + + /// + /// 初始化单机模式版本资源列表的新实例。 + /// + /// 适配的游戏版本号。 + /// 内部资源版本号。 + /// 包含的资源集合。 + /// 包含的资源集合。 + /// 包含的文件系统集合。 + /// 包含的资源组集合。 + public PackageVersionList(string applicableGameVersion, int internalResourceVersion, Asset[] assets, Resource[] resources, FileSystem[] fileSystems, ResourceGroup[] resourceGroups) + { + m_IsValid = true; + m_ApplicableGameVersion = applicableGameVersion; + m_InternalResourceVersion = internalResourceVersion; + m_Assets = assets ?? EmptyAssetArray; + m_Resources = resources ?? EmptyResourceArray; + m_FileSystems = fileSystems ?? EmptyFileSystemArray; + m_ResourceGroups = resourceGroups ?? EmptyResourceGroupArray; + } + + /// + /// 获取单机模式版本资源列表是否有效。 + /// + public bool IsValid + { + get + { + return m_IsValid; + } + } + + /// + /// 获取适配的游戏版本号。 + /// + public string ApplicableGameVersion + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_ApplicableGameVersion; + } + } + + /// + /// 获取内部资源版本号。 + /// + public int InternalResourceVersion + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_InternalResourceVersion; + } + } + + /// + /// 获取包含的资源集合。 + /// + /// 包含的资源集合。 + public Asset[] GetAssets() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Assets; + } + + /// + /// 获取包含的资源集合。 + /// + /// 包含的资源集合。 + public Resource[] GetResources() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Resources; + } + + /// + /// 获取包含的文件系统集合。 + /// + /// 包含的文件系统集合。 + public FileSystem[] GetFileSystems() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_FileSystems; + } + + /// + /// 获取包含的资源组集合。 + /// + /// 包含的资源组集合。 + public ResourceGroup[] GetResourceGroups() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_ResourceGroups; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.cs.meta new file mode 100644 index 0000000..2bc8e96 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d5e53fcb4372f2d47ae1e6ecc270f6e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionListSerializer.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionListSerializer.cs new file mode 100644 index 0000000..9038174 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionListSerializer.cs @@ -0,0 +1,33 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 单机模式版本资源列表序列化器。 + /// + public sealed class PackageVersionListSerializer : GameFrameworkSerializer + { + private static readonly byte[] Header = new byte[] { (byte)'G', (byte)'F', (byte)'P' }; + + /// + /// 初始化单机模式版本资源列表序列化器的新实例。 + /// + public PackageVersionListSerializer() + { + } + + /// + /// 获取单机模式版本资源列表头标识。 + /// + /// 单机模式版本资源列表头标识。 + protected override byte[] GetHeader() + { + return Header; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionListSerializer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionListSerializer.cs.meta new file mode 100644 index 0000000..bbd87fb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/PackageVersionListSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1b4d29b939c45145b82e040105fa8c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadOnlyVersionListSerializer.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadOnlyVersionListSerializer.cs new file mode 100644 index 0000000..6defb90 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadOnlyVersionListSerializer.cs @@ -0,0 +1,33 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 本地只读区版本资源列表序列化器。 + /// + public sealed class ReadOnlyVersionListSerializer : GameFrameworkSerializer + { + private static readonly byte[] Header = new byte[] { (byte)'G', (byte)'F', (byte)'R' }; + + /// + /// 初始化本地只读区版本资源列表序列化器的新实例。 + /// + public ReadOnlyVersionListSerializer() + { + } + + /// + /// 获取本地只读区版本资源列表头标识。 + /// + /// 本地只读区版本资源列表头标识。 + protected override byte[] GetHeader() + { + return Header; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadOnlyVersionListSerializer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadOnlyVersionListSerializer.cs.meta new file mode 100644 index 0000000..9bd3003 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadOnlyVersionListSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9df2e7fdb235ea41ae67dc1278526b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadWriteVersionListSerializer.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadWriteVersionListSerializer.cs new file mode 100644 index 0000000..1c902ed --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadWriteVersionListSerializer.cs @@ -0,0 +1,33 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 本地读写区版本资源列表序列化器。 + /// + public sealed class ReadWriteVersionListSerializer : GameFrameworkSerializer + { + private static readonly byte[] Header = new byte[] { (byte)'G', (byte)'F', (byte)'W' }; + + /// + /// 初始化本地读写区版本资源列表序列化器的新实例。 + /// + public ReadWriteVersionListSerializer() + { + } + + /// + /// 获取本地读写区版本资源列表头标识。 + /// + /// 本地读写区版本资源列表头标识。 + protected override byte[] GetHeader() + { + return Header; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadWriteVersionListSerializer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadWriteVersionListSerializer.cs.meta new file mode 100644 index 0000000..5b9d641 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ReadWriteVersionListSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d293be354d6aff6429b6418f6918278f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyFailureEventArgs.cs new file mode 100644 index 0000000..5ca3bef --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyFailureEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源应用失败事件。 + /// + public sealed class ResourceApplyFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源应用失败事件的新实例。 + /// + public ResourceApplyFailureEventArgs() + { + Name = null; + ResourcePackPath = null; + ErrorMessage = null; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源包路径。 + /// + public string ResourcePackPath + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建资源应用失败事件。 + /// + /// 资源名称。 + /// 资源包路径。 + /// 错误信息。 + /// 创建的资源应用失败事件。 + public static ResourceApplyFailureEventArgs Create(string name, string resourcePackPath, string errorMessage) + { + ResourceApplyFailureEventArgs resourceApplyFailureEventArgs = ReferencePool.Acquire(); + resourceApplyFailureEventArgs.Name = name; + resourceApplyFailureEventArgs.ResourcePackPath = resourcePackPath; + resourceApplyFailureEventArgs.ErrorMessage = errorMessage; + return resourceApplyFailureEventArgs; + } + + /// + /// 清理资源应用失败事件。 + /// + public override void Clear() + { + Name = null; + ResourcePackPath = null; + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyFailureEventArgs.cs.meta new file mode 100644 index 0000000..cf5c442 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20d2dfd031d751f45b076a4947ef2cc0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyStartEventArgs.cs new file mode 100644 index 0000000..f3876d1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyStartEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源应用开始事件。 + /// + public sealed class ResourceApplyStartEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源应用开始事件的新实例。 + /// + public ResourceApplyStartEventArgs() + { + ResourcePackPath = null; + Count = 0; + TotalLength = 0L; + } + + /// + /// 获取资源包路径。 + /// + public string ResourcePackPath + { + get; + private set; + } + + /// + /// 获取要应用资源的数量。 + /// + public int Count + { + get; + private set; + } + + /// + /// 获取要应用资源的总大小。 + /// + public long TotalLength + { + get; + private set; + } + + /// + /// 创建资源应用开始事件。 + /// + /// 资源包路径。 + /// 要应用资源的数量。 + /// 要应用资源的总大小。 + /// 创建的资源应用开始事件。 + public static ResourceApplyStartEventArgs Create(string resourcePackPath, int count, long totalLength) + { + ResourceApplyStartEventArgs resourceApplyStartEventArgs = ReferencePool.Acquire(); + resourceApplyStartEventArgs.ResourcePackPath = resourcePackPath; + resourceApplyStartEventArgs.Count = count; + resourceApplyStartEventArgs.TotalLength = totalLength; + return resourceApplyStartEventArgs; + } + + /// + /// 清理资源应用开始事件。 + /// + public override void Clear() + { + ResourcePackPath = null; + Count = 0; + TotalLength = 0L; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyStartEventArgs.cs.meta new file mode 100644 index 0000000..803c715 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplyStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 768c9181bf35bfd4cb58405d11b7ffcc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplySuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplySuccessEventArgs.cs new file mode 100644 index 0000000..a73a332 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplySuccessEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源应用成功事件。 + /// + public sealed class ResourceApplySuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源应用成功事件的新实例。 + /// + public ResourceApplySuccessEventArgs() + { + Name = null; + ApplyPath = null; + ResourcePackPath = null; + Length = 0; + CompressedLength = 0; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源应用后存放路径。 + /// + public string ApplyPath + { + get; + private set; + } + + /// + /// 获取资源包路径。 + /// + public string ResourcePackPath + { + get; + private set; + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get; + private set; + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get; + private set; + } + + /// + /// 创建资源应用成功事件。 + /// + /// 资源名称。 + /// 资源应用后存放路径。 + /// 资源包路径。 + /// 资源大小。 + /// 压缩后大小。 + /// 创建的资源应用成功事件。 + public static ResourceApplySuccessEventArgs Create(string name, string applyPath, string resourcePackPath, int length, int compressedLength) + { + ResourceApplySuccessEventArgs resourceApplySuccessEventArgs = ReferencePool.Acquire(); + resourceApplySuccessEventArgs.Name = name; + resourceApplySuccessEventArgs.ApplyPath = applyPath; + resourceApplySuccessEventArgs.ResourcePackPath = resourcePackPath; + resourceApplySuccessEventArgs.Length = length; + resourceApplySuccessEventArgs.CompressedLength = compressedLength; + return resourceApplySuccessEventArgs; + } + + /// + /// 清理资源应用成功事件。 + /// + public override void Clear() + { + Name = null; + ApplyPath = null; + ResourcePackPath = null; + Length = 0; + CompressedLength = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplySuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplySuccessEventArgs.cs.meta new file mode 100644 index 0000000..5d589fc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceApplySuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 153f8f2935dc18742bd4781344e46d6f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.AssetInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.AssetInfo.cs new file mode 100644 index 0000000..6785c2e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.AssetInfo.cs @@ -0,0 +1,66 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源信息。 + /// + private sealed class AssetInfo + { + private readonly string m_AssetName; + private readonly ResourceName m_ResourceName; + private readonly string[] m_DependencyAssetNames; + + /// + /// 初始化资源信息的新实例。 + /// + /// 资源名称。 + /// 所在资源名称。 + /// 依赖资源名称。 + public AssetInfo(string assetName, ResourceName resourceName, string[] dependencyAssetNames) + { + m_AssetName = assetName; + m_ResourceName = resourceName; + m_DependencyAssetNames = dependencyAssetNames; + } + + /// + /// 获取资源名称。 + /// + public string AssetName + { + get + { + return m_AssetName; + } + } + + /// + /// 获取所在资源名称。 + /// + public ResourceName ResourceName + { + get + { + return m_ResourceName; + } + } + + /// + /// 获取依赖资源名称。 + /// + /// 依赖资源名称。 + public string[] GetDependencyAssetNames() + { + return m_DependencyAssetNames; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.AssetInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.AssetInfo.cs.meta new file mode 100644 index 0000000..a09e055 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.AssetInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1633c7761e28c684ba95f6de18754a11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.LoadType.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.LoadType.cs new file mode 100644 index 0000000..43825af --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.LoadType.cs @@ -0,0 +1,53 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源加载方式类型。 + /// + private enum LoadType : byte + { + /// + /// 使用文件方式加载。 + /// + LoadFromFile = 0, + + /// + /// 使用内存方式加载。 + /// + LoadFromMemory, + + /// + /// 使用内存快速解密方式加载。 + /// + LoadFromMemoryAndQuickDecrypt, + + /// + /// 使用内存解密方式加载。 + /// + LoadFromMemoryAndDecrypt, + + /// + /// 使用二进制方式加载。 + /// + LoadFromBinary, + + /// + /// 使用二进制快速解密方式加载。 + /// + LoadFromBinaryAndQuickDecrypt, + + /// + /// 使用二进制解密方式加载。 + /// + LoadFromBinaryAndDecrypt + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.LoadType.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.LoadType.cs.meta new file mode 100644 index 0000000..f0831cb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.LoadType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f80a78eb134c7b54c9689ef5f576d060 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ReadWriteResourceInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ReadWriteResourceInfo.cs new file mode 100644 index 0000000..d349fb2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ReadWriteResourceInfo.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + [StructLayout(LayoutKind.Auto)] + private struct ReadWriteResourceInfo + { + private readonly string m_FileSystemName; + private readonly LoadType m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + + public ReadWriteResourceInfo(string fileSystemName, LoadType loadType, int length, int hashCode) + { + m_FileSystemName = fileSystemName; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + } + + public bool UseFileSystem + { + get + { + return !string.IsNullOrEmpty(m_FileSystemName); + } + } + + public string FileSystemName + { + get + { + return m_FileSystemName; + } + } + + public LoadType LoadType + { + get + { + return m_LoadType; + } + } + + public int Length + { + get + { + return m_Length; + } + } + + public int HashCode + { + get + { + return m_HashCode; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ReadWriteResourceInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ReadWriteResourceInfo.cs.meta new file mode 100644 index 0000000..aa1c9d8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ReadWriteResourceInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5df9583e4b16e6a4689994eb8b4274c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.CheckStatus.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.CheckStatus.cs new file mode 100644 index 0000000..5ab17ee --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.CheckStatus.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceChecker + { + private sealed partial class CheckInfo + { + /// + /// 资源检查状态。 + /// + public enum CheckStatus : byte + { + /// + /// 资源状态未知。 + /// + Unknown = 0, + + /// + /// 资源存在且已存放于只读区中。 + /// + StorageInReadOnly, + + /// + /// 资源存在且已存放于读写区中。 + /// + StorageInReadWrite, + + /// + /// 资源不适用于当前变体。 + /// + Unavailable, + + /// + /// 资源需要更新。 + /// + Update, + + /// + /// 资源已废弃。 + /// + Disuse + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.CheckStatus.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.CheckStatus.cs.meta new file mode 100644 index 0000000..24ace59 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.CheckStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9023ed109aaff4f4597d3f65cd5fe728 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.LocalVersionInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.LocalVersionInfo.cs new file mode 100644 index 0000000..4f22410 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.LocalVersionInfo.cs @@ -0,0 +1,90 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceChecker + { + private sealed partial class CheckInfo + { + /// + /// 本地资源状态信息。 + /// + [StructLayout(LayoutKind.Auto)] + private struct LocalVersionInfo + { + private readonly bool m_Exist; + private readonly string m_FileSystemName; + private readonly LoadType m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + + public LocalVersionInfo(string fileSystemName, LoadType loadType, int length, int hashCode) + { + m_Exist = true; + m_FileSystemName = fileSystemName; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + } + + public bool Exist + { + get + { + return m_Exist; + } + } + + public bool UseFileSystem + { + get + { + return !string.IsNullOrEmpty(m_FileSystemName); + } + } + + public string FileSystemName + { + get + { + return m_FileSystemName; + } + } + + public LoadType LoadType + { + get + { + return m_LoadType; + } + } + + public int Length + { + get + { + return m_Length; + } + } + + public int HashCode + { + get + { + return m_HashCode; + } + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.LocalVersionInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.LocalVersionInfo.cs.meta new file mode 100644 index 0000000..e750697 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.LocalVersionInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca0996f92a26ed847ae157c9b17d2493 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.RemoteVersionInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.RemoteVersionInfo.cs new file mode 100644 index 0000000..52bb19e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.RemoteVersionInfo.cs @@ -0,0 +1,110 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceChecker + { + private sealed partial class CheckInfo + { + /// + /// 远程资源状态信息。 + /// + [StructLayout(LayoutKind.Auto)] + private struct RemoteVersionInfo + { + private readonly bool m_Exist; + private readonly string m_FileSystemName; + private readonly LoadType m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly int m_CompressedLength; + private readonly int m_CompressedHashCode; + + public RemoteVersionInfo(string fileSystemName, LoadType loadType, int length, int hashCode, int compressedLength, int compressedHashCode) + { + m_Exist = true; + m_FileSystemName = fileSystemName; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + m_CompressedLength = compressedLength; + m_CompressedHashCode = compressedHashCode; + } + + public bool Exist + { + get + { + return m_Exist; + } + } + + public bool UseFileSystem + { + get + { + return !string.IsNullOrEmpty(m_FileSystemName); + } + } + + public string FileSystemName + { + get + { + return m_FileSystemName; + } + } + + public LoadType LoadType + { + get + { + return m_LoadType; + } + } + + public int Length + { + get + { + return m_Length; + } + } + + public int HashCode + { + get + { + return m_HashCode; + } + } + + public int CompressedLength + { + get + { + return m_CompressedLength; + } + } + + public int CompressedHashCode + { + get + { + return m_CompressedHashCode; + } + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.RemoteVersionInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.RemoteVersionInfo.cs.meta new file mode 100644 index 0000000..0ffe6c0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.RemoteVersionInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: add43398f3488a34889bbaf753a6a4ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.cs new file mode 100644 index 0000000..683f808 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.cs @@ -0,0 +1,294 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceChecker + { + /// + /// 资源检查信息。 + /// + private sealed partial class CheckInfo + { + private readonly ResourceName m_ResourceName; + private CheckStatus m_Status; + private bool m_NeedRemove; + private bool m_NeedMoveToDisk; + private bool m_NeedMoveToFileSystem; + private RemoteVersionInfo m_VersionInfo; + private LocalVersionInfo m_ReadOnlyInfo; + private LocalVersionInfo m_ReadWriteInfo; + private string m_CachedFileSystemName; + + /// + /// 初始化资源检查信息的新实例。 + /// + /// 资源名称。 + public CheckInfo(ResourceName resourceName) + { + m_ResourceName = resourceName; + m_Status = CheckStatus.Unknown; + m_NeedRemove = false; + m_NeedMoveToDisk = false; + m_NeedMoveToFileSystem = false; + m_VersionInfo = default(RemoteVersionInfo); + m_ReadOnlyInfo = default(LocalVersionInfo); + m_ReadWriteInfo = default(LocalVersionInfo); + m_CachedFileSystemName = null; + } + + /// + /// 获取资源名称。 + /// + public ResourceName ResourceName + { + get + { + return m_ResourceName; + } + } + + /// + /// 获取资源检查状态。 + /// + public CheckStatus Status + { + get + { + return m_Status; + } + } + + /// + /// 获取是否需要移除读写区的资源。 + /// + public bool NeedRemove + { + get + { + return m_NeedRemove; + } + } + + /// + /// 获取是否需要将读写区的资源移动到磁盘。 + /// + public bool NeedMoveToDisk + { + get + { + return m_NeedMoveToDisk; + } + } + + /// + /// 获取是否需要将读写区的资源移动到文件系统。 + /// + public bool NeedMoveToFileSystem + { + get + { + return m_NeedMoveToFileSystem; + } + } + + /// + /// 获取资源所在的文件系统名称。 + /// + public string FileSystemName + { + get + { + return m_VersionInfo.FileSystemName; + } + } + + /// + /// 获取资源是否使用文件系统。 + /// + public bool ReadWriteUseFileSystem + { + get + { + return m_ReadWriteInfo.UseFileSystem; + } + } + + /// + /// 获取读写资源所在的文件系统名称。 + /// + public string ReadWriteFileSystemName + { + get + { + return m_ReadWriteInfo.FileSystemName; + } + } + + /// + /// 获取资源加载方式。 + /// + public LoadType LoadType + { + get + { + return m_VersionInfo.LoadType; + } + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get + { + return m_VersionInfo.Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_VersionInfo.HashCode; + } + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get + { + return m_VersionInfo.CompressedLength; + } + } + + /// + /// 获取压缩后哈希值。 + /// + public int CompressedHashCode + { + get + { + return m_VersionInfo.CompressedHashCode; + } + } + + /// + /// 临时缓存资源所在的文件系统名称。 + /// + /// 资源所在的文件系统名称。 + public void SetCachedFileSystemName(string fileSystemName) + { + m_CachedFileSystemName = fileSystemName; + } + + /// + /// 设置资源在版本中的信息。 + /// + /// 资源加载方式。 + /// 资源大小。 + /// 资源哈希值。 + /// 压缩后大小。 + /// 压缩后哈希值。 + public void SetVersionInfo(LoadType loadType, int length, int hashCode, int compressedLength, int compressedHashCode) + { + if (m_VersionInfo.Exist) + { + throw new GameFrameworkException(Utility.Text.Format("You must set version info of '{0}' only once.", m_ResourceName.FullName)); + } + + m_VersionInfo = new RemoteVersionInfo(m_CachedFileSystemName, loadType, length, hashCode, compressedLength, compressedHashCode); + m_CachedFileSystemName = null; + } + + /// + /// 设置资源在只读区中的信息。 + /// + /// 资源加载方式。 + /// 资源大小。 + /// 资源哈希值。 + public void SetReadOnlyInfo(LoadType loadType, int length, int hashCode) + { + if (m_ReadOnlyInfo.Exist) + { + throw new GameFrameworkException(Utility.Text.Format("You must set read-only info of '{0}' only once.", m_ResourceName.FullName)); + } + + m_ReadOnlyInfo = new LocalVersionInfo(m_CachedFileSystemName, loadType, length, hashCode); + m_CachedFileSystemName = null; + } + + /// + /// 设置资源在读写区中的信息。 + /// + /// 资源加载方式。 + /// 资源大小。 + /// 资源哈希值。 + public void SetReadWriteInfo(LoadType loadType, int length, int hashCode) + { + if (m_ReadWriteInfo.Exist) + { + throw new GameFrameworkException(Utility.Text.Format("You must set read-write info of '{0}' only once.", m_ResourceName.FullName)); + } + + m_ReadWriteInfo = new LocalVersionInfo(m_CachedFileSystemName, loadType, length, hashCode); + m_CachedFileSystemName = null; + } + + /// + /// 刷新资源信息状态。 + /// + /// 当前变体。 + /// 是否忽略处理其它变体的资源,若不忽略则移除。 + public void RefreshStatus(string currentVariant, bool ignoreOtherVariant) + { + if (!m_VersionInfo.Exist) + { + m_Status = CheckStatus.Disuse; + m_NeedRemove = m_ReadWriteInfo.Exist; + return; + } + + if (m_ResourceName.Variant == null || m_ResourceName.Variant == currentVariant) + { + if (m_ReadOnlyInfo.Exist && m_ReadOnlyInfo.FileSystemName == m_VersionInfo.FileSystemName && m_ReadOnlyInfo.LoadType == m_VersionInfo.LoadType && m_ReadOnlyInfo.Length == m_VersionInfo.Length && m_ReadOnlyInfo.HashCode == m_VersionInfo.HashCode) + { + m_Status = CheckStatus.StorageInReadOnly; + m_NeedRemove = m_ReadWriteInfo.Exist; + } + else if (m_ReadWriteInfo.Exist && m_ReadWriteInfo.LoadType == m_VersionInfo.LoadType && m_ReadWriteInfo.Length == m_VersionInfo.Length && m_ReadWriteInfo.HashCode == m_VersionInfo.HashCode) + { + bool differentFileSystem = m_ReadWriteInfo.FileSystemName != m_VersionInfo.FileSystemName; + m_Status = CheckStatus.StorageInReadWrite; + m_NeedMoveToDisk = m_ReadWriteInfo.UseFileSystem && differentFileSystem; + m_NeedMoveToFileSystem = m_VersionInfo.UseFileSystem && differentFileSystem; + } + else + { + m_Status = CheckStatus.Update; + m_NeedRemove = m_ReadWriteInfo.Exist; + } + } + else + { + m_Status = CheckStatus.Unavailable; + m_NeedRemove = !ignoreOtherVariant && m_ReadWriteInfo.Exist; + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.cs.meta new file mode 100644 index 0000000..8ceee72 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.CheckInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 988112be151e0834b9167d7c593ede8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.cs new file mode 100644 index 0000000..e3e9431 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.cs @@ -0,0 +1,505 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; +using System; +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源检查器。 + /// + private sealed partial class ResourceChecker + { + private readonly ResourceManager m_ResourceManager; + private readonly Dictionary m_CheckInfos; + private string m_CurrentVariant; + private bool m_IgnoreOtherVariant; + private bool m_UpdatableVersionListReady; + private bool m_ReadOnlyVersionListReady; + private bool m_ReadWriteVersionListReady; + + public GameFrameworkAction ResourceNeedUpdate; + public GameFrameworkAction ResourceCheckComplete; + + /// + /// 初始化资源检查器的新实例。 + /// + /// 资源管理器。 + public ResourceChecker(ResourceManager resourceManager) + { + m_ResourceManager = resourceManager; + m_CheckInfos = new Dictionary(); + m_CurrentVariant = null; + m_IgnoreOtherVariant = false; + m_UpdatableVersionListReady = false; + m_ReadOnlyVersionListReady = false; + m_ReadWriteVersionListReady = false; + + ResourceNeedUpdate = null; + ResourceCheckComplete = null; + } + + /// + /// 关闭并清理资源检查器。 + /// + public void Shutdown() + { + m_CheckInfos.Clear(); + } + + /// + /// 检查资源。 + /// + /// 当前使用的变体。 + /// 是否忽略处理其它变体的资源,若不忽略,将会移除其它变体的资源。 + public void CheckResources(string currentVariant, bool ignoreOtherVariant) + { + if (m_ResourceManager.m_ResourceHelper == null) + { + throw new GameFrameworkException("Resource helper is invalid."); + } + + if (string.IsNullOrEmpty(m_ResourceManager.m_ReadOnlyPath)) + { + throw new GameFrameworkException("Read-only path is invalid."); + } + + if (string.IsNullOrEmpty(m_ResourceManager.m_ReadWritePath)) + { + throw new GameFrameworkException("Read-write path is invalid."); + } + + m_CurrentVariant = currentVariant; + m_IgnoreOtherVariant = ignoreOtherVariant; + m_ResourceManager.m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_ReadWritePath, RemoteVersionListFileName)), new LoadBytesCallbacks(OnLoadUpdatableVersionListSuccess, OnLoadUpdatableVersionListFailure), null); + m_ResourceManager.m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_ReadOnlyPath, LocalVersionListFileName)), new LoadBytesCallbacks(OnLoadReadOnlyVersionListSuccess, OnLoadReadOnlyVersionListFailure), null); + m_ResourceManager.m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_ReadWritePath, LocalVersionListFileName)), new LoadBytesCallbacks(OnLoadReadWriteVersionListSuccess, OnLoadReadWriteVersionListFailure), null); + } + + private void SetCachedFileSystemName(ResourceName resourceName, string fileSystemName) + { + GetOrAddCheckInfo(resourceName).SetCachedFileSystemName(fileSystemName); + } + + private void SetVersionInfo(ResourceName resourceName, LoadType loadType, int length, int hashCode, int compressedLength, int compressedHashCode) + { + GetOrAddCheckInfo(resourceName).SetVersionInfo(loadType, length, hashCode, compressedLength, compressedHashCode); + } + + private void SetReadOnlyInfo(ResourceName resourceName, LoadType loadType, int length, int hashCode) + { + GetOrAddCheckInfo(resourceName).SetReadOnlyInfo(loadType, length, hashCode); + } + + private void SetReadWriteInfo(ResourceName resourceName, LoadType loadType, int length, int hashCode) + { + GetOrAddCheckInfo(resourceName).SetReadWriteInfo(loadType, length, hashCode); + } + + private CheckInfo GetOrAddCheckInfo(ResourceName resourceName) + { + CheckInfo checkInfo = null; + if (m_CheckInfos.TryGetValue(resourceName, out checkInfo)) + { + return checkInfo; + } + + checkInfo = new CheckInfo(resourceName); + m_CheckInfos.Add(checkInfo.ResourceName, checkInfo); + + return checkInfo; + } + + private void RefreshCheckInfoStatus() + { + if (!m_UpdatableVersionListReady || !m_ReadOnlyVersionListReady || !m_ReadWriteVersionListReady) + { + return; + } + + int movedCount = 0; + int removedCount = 0; + int updateCount = 0; + long updateTotalLength = 0L; + long updateTotalCompressedLength = 0L; + foreach (KeyValuePair checkInfo in m_CheckInfos) + { + CheckInfo ci = checkInfo.Value; + ci.RefreshStatus(m_CurrentVariant, m_IgnoreOtherVariant); + if (ci.Status == CheckInfo.CheckStatus.StorageInReadOnly) + { + m_ResourceManager.m_ResourceInfos.Add(ci.ResourceName, new ResourceInfo(ci.ResourceName, ci.FileSystemName, ci.LoadType, ci.Length, ci.HashCode, ci.CompressedLength, true, true)); + } + else if (ci.Status == CheckInfo.CheckStatus.StorageInReadWrite) + { + if (ci.NeedMoveToDisk || ci.NeedMoveToFileSystem) + { + movedCount++; + string resourceFullName = ci.ResourceName.FullName; + string resourcePath = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.m_ReadWritePath, resourceFullName)); + if (ci.NeedMoveToDisk) + { + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(ci.ReadWriteFileSystemName, false); + if (!fileSystem.SaveAsFile(resourceFullName, resourcePath)) + { + throw new GameFrameworkException(Utility.Text.Format("Save as file '{0}' to '{1}' from file system '{2}' error.", resourceFullName, resourcePath, fileSystem.FullPath)); + } + + fileSystem.DeleteFile(resourceFullName); + } + + if (ci.NeedMoveToFileSystem) + { + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(ci.FileSystemName, false); + if (!fileSystem.WriteFile(resourceFullName, resourcePath)) + { + throw new GameFrameworkException(Utility.Text.Format("Write resource '{0}' to file system '{1}' error.", resourceFullName, fileSystem.FullPath)); + } + + if (File.Exists(resourcePath)) + { + File.Delete(resourcePath); + } + } + } + + m_ResourceManager.m_ResourceInfos.Add(ci.ResourceName, new ResourceInfo(ci.ResourceName, ci.FileSystemName, ci.LoadType, ci.Length, ci.HashCode, ci.CompressedLength, false, true)); + m_ResourceManager.m_ReadWriteResourceInfos.Add(ci.ResourceName, new ReadWriteResourceInfo(ci.FileSystemName, ci.LoadType, ci.Length, ci.HashCode)); + } + else if (ci.Status == CheckInfo.CheckStatus.Update) + { + m_ResourceManager.m_ResourceInfos.Add(ci.ResourceName, new ResourceInfo(ci.ResourceName, ci.FileSystemName, ci.LoadType, ci.Length, ci.HashCode, ci.CompressedLength, false, false)); + updateCount++; + updateTotalLength += ci.Length; + updateTotalCompressedLength += ci.CompressedLength; + if (ResourceNeedUpdate != null) + { + ResourceNeedUpdate(ci.ResourceName, ci.FileSystemName, ci.LoadType, ci.Length, ci.HashCode, ci.CompressedLength, ci.CompressedHashCode); + } + } + else if (ci.Status == CheckInfo.CheckStatus.Unavailable || ci.Status == CheckInfo.CheckStatus.Disuse) + { + // Do nothing. + } + else + { + throw new GameFrameworkException(Utility.Text.Format("Check resources '{0}' error with unknown status.", ci.ResourceName.FullName)); + } + + if (ci.NeedRemove) + { + removedCount++; + if (ci.ReadWriteUseFileSystem) + { + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(ci.ReadWriteFileSystemName, false); + fileSystem.DeleteFile(ci.ResourceName.FullName); + } + else + { + string resourcePath = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.m_ReadWritePath, ci.ResourceName.FullName)); + if (File.Exists(resourcePath)) + { + File.Delete(resourcePath); + } + } + } + } + + if (movedCount > 0 || removedCount > 0) + { + RemoveEmptyFileSystems(); + Utility.Path.RemoveEmptyDirectory(m_ResourceManager.m_ReadWritePath); + } + + if (ResourceCheckComplete != null) + { + ResourceCheckComplete(movedCount, removedCount, updateCount, updateTotalLength, updateTotalCompressedLength); + } + } + + private void RemoveEmptyFileSystems() + { + List removedFileSystemNames = null; + foreach (KeyValuePair fileSystem in m_ResourceManager.m_ReadWriteFileSystems) + { + if (fileSystem.Value.FileCount <= 0) + { + if (removedFileSystemNames == null) + { + removedFileSystemNames = new List(); + } + + m_ResourceManager.m_FileSystemManager.DestroyFileSystem(fileSystem.Value, true); + removedFileSystemNames.Add(fileSystem.Key); + } + } + + if (removedFileSystemNames != null) + { + foreach (string removedFileSystemName in removedFileSystemNames) + { + m_ResourceManager.m_ReadWriteFileSystems.Remove(removedFileSystemName); + } + } + } + + private void OnLoadUpdatableVersionListSuccess(string fileUri, byte[] bytes, float duration, object userData) + { + if (m_UpdatableVersionListReady) + { + throw new GameFrameworkException("Updatable version list has been parsed."); + } + + MemoryStream memoryStream = null; + try + { + memoryStream = new MemoryStream(bytes, false); + UpdatableVersionList versionList = m_ResourceManager.m_UpdatableVersionListSerializer.Deserialize(memoryStream); + if (!versionList.IsValid) + { + throw new GameFrameworkException("Deserialize updatable version list failure."); + } + + UpdatableVersionList.Asset[] assets = versionList.GetAssets(); + UpdatableVersionList.Resource[] resources = versionList.GetResources(); + UpdatableVersionList.FileSystem[] fileSystems = versionList.GetFileSystems(); + UpdatableVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); + m_ResourceManager.m_ApplicableGameVersion = versionList.ApplicableGameVersion; + m_ResourceManager.m_InternalResourceVersion = versionList.InternalResourceVersion; + m_ResourceManager.m_AssetInfos = new Dictionary(assets.Length, StringComparer.Ordinal); + m_ResourceManager.m_ResourceInfos = new Dictionary(resources.Length, new ResourceNameComparer()); + m_ResourceManager.m_ReadWriteResourceInfos = new SortedDictionary(new ResourceNameComparer()); + ResourceGroup defaultResourceGroup = m_ResourceManager.GetOrAddResourceGroup(string.Empty); + + foreach (UpdatableVersionList.FileSystem fileSystem in fileSystems) + { + int[] resourceIndexes = fileSystem.GetResourceIndexes(); + foreach (int resourceIndex in resourceIndexes) + { + UpdatableVersionList.Resource resource = resources[resourceIndex]; + if (resource.Variant != null && resource.Variant != m_CurrentVariant) + { + continue; + } + + SetCachedFileSystemName(new ResourceName(resource.Name, resource.Variant, resource.Extension), fileSystem.Name); + } + } + + foreach (UpdatableVersionList.Resource resource in resources) + { + if (resource.Variant != null && resource.Variant != m_CurrentVariant) + { + continue; + } + + ResourceName resourceName = new ResourceName(resource.Name, resource.Variant, resource.Extension); + int[] assetIndexes = resource.GetAssetIndexes(); + foreach (int assetIndex in assetIndexes) + { + UpdatableVersionList.Asset asset = assets[assetIndex]; + int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); + int index = 0; + string[] dependencyAssetNames = new string[dependencyAssetIndexes.Length]; + foreach (int dependencyAssetIndex in dependencyAssetIndexes) + { + dependencyAssetNames[index++] = assets[dependencyAssetIndex].Name; + } + + m_ResourceManager.m_AssetInfos.Add(asset.Name, new AssetInfo(asset.Name, resourceName, dependencyAssetNames)); + } + + SetVersionInfo(resourceName, (LoadType)resource.LoadType, resource.Length, resource.HashCode, resource.CompressedLength, resource.CompressedHashCode); + defaultResourceGroup.AddResource(resourceName, resource.Length, resource.CompressedLength); + } + + foreach (UpdatableVersionList.ResourceGroup resourceGroup in resourceGroups) + { + ResourceGroup group = m_ResourceManager.GetOrAddResourceGroup(resourceGroup.Name); + int[] resourceIndexes = resourceGroup.GetResourceIndexes(); + foreach (int resourceIndex in resourceIndexes) + { + UpdatableVersionList.Resource resource = resources[resourceIndex]; + if (resource.Variant != null && resource.Variant != m_CurrentVariant) + { + continue; + } + + group.AddResource(new ResourceName(resource.Name, resource.Variant, resource.Extension), resource.Length, resource.CompressedLength); + } + } + + m_UpdatableVersionListReady = true; + RefreshCheckInfoStatus(); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Parse updatable version list exception '{0}'.", exception), exception); + } + finally + { + if (memoryStream != null) + { + memoryStream.Dispose(); + memoryStream = null; + } + } + } + + private void OnLoadUpdatableVersionListFailure(string fileUri, string errorMessage, object userData) + { + throw new GameFrameworkException(Utility.Text.Format("Updatable version list '{0}' is invalid, error message is '{1}'.", fileUri, string.IsNullOrEmpty(errorMessage) ? "" : errorMessage)); + } + + private void OnLoadReadOnlyVersionListSuccess(string fileUri, byte[] bytes, float duration, object userData) + { + if (m_ReadOnlyVersionListReady) + { + throw new GameFrameworkException("Read-only version list has been parsed."); + } + + MemoryStream memoryStream = null; + try + { + memoryStream = new MemoryStream(bytes, false); + LocalVersionList versionList = m_ResourceManager.m_ReadOnlyVersionListSerializer.Deserialize(memoryStream); + if (!versionList.IsValid) + { + throw new GameFrameworkException("Deserialize read-only version list failure."); + } + + LocalVersionList.Resource[] resources = versionList.GetResources(); + LocalVersionList.FileSystem[] fileSystems = versionList.GetFileSystems(); + + foreach (LocalVersionList.FileSystem fileSystem in fileSystems) + { + int[] resourceIndexes = fileSystem.GetResourceIndexes(); + foreach (int resourceIndex in resourceIndexes) + { + LocalVersionList.Resource resource = resources[resourceIndex]; + SetCachedFileSystemName(new ResourceName(resource.Name, resource.Variant, resource.Extension), fileSystem.Name); + } + } + + foreach (LocalVersionList.Resource resource in resources) + { + SetReadOnlyInfo(new ResourceName(resource.Name, resource.Variant, resource.Extension), (LoadType)resource.LoadType, resource.Length, resource.HashCode); + } + + m_ReadOnlyVersionListReady = true; + RefreshCheckInfoStatus(); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Parse read-only version list exception '{0}'.", exception), exception); + } + finally + { + if (memoryStream != null) + { + memoryStream.Dispose(); + memoryStream = null; + } + } + } + + private void OnLoadReadOnlyVersionListFailure(string fileUri, string errorMessage, object userData) + { + if (m_ReadOnlyVersionListReady) + { + throw new GameFrameworkException("Read-only version list has been parsed."); + } + + m_ReadOnlyVersionListReady = true; + RefreshCheckInfoStatus(); + } + + private void OnLoadReadWriteVersionListSuccess(string fileUri, byte[] bytes, float duration, object userData) + { + if (m_ReadWriteVersionListReady) + { + throw new GameFrameworkException("Read-write version list has been parsed."); + } + + MemoryStream memoryStream = null; + try + { + memoryStream = new MemoryStream(bytes, false); + LocalVersionList versionList = m_ResourceManager.m_ReadWriteVersionListSerializer.Deserialize(memoryStream); + if (!versionList.IsValid) + { + throw new GameFrameworkException("Deserialize read-write version list failure."); + } + + LocalVersionList.Resource[] resources = versionList.GetResources(); + LocalVersionList.FileSystem[] fileSystems = versionList.GetFileSystems(); + + foreach (LocalVersionList.FileSystem fileSystem in fileSystems) + { + int[] resourceIndexes = fileSystem.GetResourceIndexes(); + foreach (int resourceIndex in resourceIndexes) + { + LocalVersionList.Resource resource = resources[resourceIndex]; + SetCachedFileSystemName(new ResourceName(resource.Name, resource.Variant, resource.Extension), fileSystem.Name); + } + } + + foreach (LocalVersionList.Resource resource in resources) + { + SetReadWriteInfo(new ResourceName(resource.Name, resource.Variant, resource.Extension), (LoadType)resource.LoadType, resource.Length, resource.HashCode); + } + + m_ReadWriteVersionListReady = true; + RefreshCheckInfoStatus(); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Parse read-write version list exception '{0}'.", exception), exception); + } + finally + { + if (memoryStream != null) + { + memoryStream.Dispose(); + memoryStream = null; + } + } + } + + private void OnLoadReadWriteVersionListFailure(string fileUri, string errorMessage, object userData) + { + if (m_ReadWriteVersionListReady) + { + throw new GameFrameworkException("Read-write version list has been parsed."); + } + + m_ReadWriteVersionListReady = true; + RefreshCheckInfoStatus(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.cs.meta new file mode 100644 index 0000000..f1b108c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceChecker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 416fabfbd0fc5c34488eaf29a88c2c92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroup.cs new file mode 100644 index 0000000..a215aad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroup.cs @@ -0,0 +1,268 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源组。 + /// + private sealed class ResourceGroup : IResourceGroup + { + private readonly string m_Name; + private readonly Dictionary m_ResourceInfos; + private readonly HashSet m_ResourceNames; + private long m_TotalLength; + private long m_TotalCompressedLength; + + /// + /// 初始化资源组的新实例。 + /// + /// 资源组名称。 + /// 资源信息引用。 + public ResourceGroup(string name, Dictionary resourceInfos) + { + if (name == null) + { + throw new GameFrameworkException("Name is invalid."); + } + + if (resourceInfos == null) + { + throw new GameFrameworkException("Resource infos is invalid."); + } + + m_Name = name; + m_ResourceInfos = resourceInfos; + m_ResourceNames = new HashSet(); + } + + /// + /// 获取资源组名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源组是否准备完毕。 + /// + public bool Ready + { + get + { + return ReadyCount >= TotalCount; + } + } + + /// + /// 获取资源组包含资源数量。 + /// + public int TotalCount + { + get + { + return m_ResourceNames.Count; + } + } + + /// + /// 获取资源组中已准备完成资源数量。 + /// + public int ReadyCount + { + get + { + int readyCount = 0; + foreach (ResourceName resourceName in m_ResourceNames) + { + ResourceInfo resourceInfo = null; + if (m_ResourceInfos.TryGetValue(resourceName, out resourceInfo) && resourceInfo.Ready) + { + readyCount++; + } + } + + return readyCount; + } + } + + /// + /// 获取资源组包含资源的总大小。 + /// + public long TotalLength + { + get + { + return m_TotalLength; + } + } + + /// + /// 获取资源组包含资源压缩后的总大小。 + /// + public long TotalCompressedLength + { + get + { + return m_TotalCompressedLength; + } + } + + /// + /// 获取资源组中已准备完成资源的总大小。 + /// + public long ReadyLength + { + get + { + long readyLength = 0L; + foreach (ResourceName resourceName in m_ResourceNames) + { + ResourceInfo resourceInfo = null; + if (m_ResourceInfos.TryGetValue(resourceName, out resourceInfo) && resourceInfo.Ready) + { + readyLength += resourceInfo.Length; + } + } + + return readyLength; + } + } + + /// + /// 获取资源组中已准备完成资源压缩后的总大小。 + /// + public long ReadyCompressedLength + { + get + { + long readyCompressedLength = 0L; + foreach (ResourceName resourceName in m_ResourceNames) + { + ResourceInfo resourceInfo = null; + if (m_ResourceInfos.TryGetValue(resourceName, out resourceInfo) && resourceInfo.Ready) + { + readyCompressedLength += resourceInfo.CompressedLength; + } + } + + return readyCompressedLength; + } + } + + /// + /// 获取资源组的完成进度。 + /// + public float Progress + { + get + { + return m_TotalLength > 0L ? (float)ReadyLength / m_TotalLength : 1f; + } + } + + /// + /// 获取资源组包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + public string[] GetResourceNames() + { + int index = 0; + string[] resourceNames = new string[m_ResourceNames.Count]; + foreach (ResourceName resourceName in m_ResourceNames) + { + resourceNames[index++] = resourceName.FullName; + } + + return resourceNames; + } + + /// + /// 获取资源组包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + public void GetResourceNames(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (ResourceName resourceName in m_ResourceNames) + { + results.Add(resourceName.FullName); + } + } + + /// + /// 获取资源组包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + public ResourceName[] InternalGetResourceNames() + { + int index = 0; + ResourceName[] resourceNames = new ResourceName[m_ResourceNames.Count]; + foreach (ResourceName resourceName in m_ResourceNames) + { + resourceNames[index++] = resourceName; + } + + return resourceNames; + } + + /// + /// 获取资源组包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + public void InternalGetResourceNames(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (ResourceName resourceName in m_ResourceNames) + { + results.Add(resourceName); + } + } + + /// + /// 检查指定资源是否属于资源组。 + /// + /// 要检查的资源的名称。 + /// 指定资源是否属于资源组。 + public bool HasResource(ResourceName resourceName) + { + return m_ResourceNames.Contains(resourceName); + } + + /// + /// 向资源组中增加资源。 + /// + /// 资源名称。 + /// 资源大小。 + /// 资源压缩后的大小。 + public void AddResource(ResourceName resourceName, int length, int compressedLength) + { + m_ResourceNames.Add(resourceName); + m_TotalLength += length; + m_TotalCompressedLength += compressedLength; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroup.cs.meta new file mode 100644 index 0000000..aec98d4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef71d0ab4a89c7e43bb7024ab1ba1176 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroupCollection.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroupCollection.cs new file mode 100644 index 0000000..8439d8b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroupCollection.cs @@ -0,0 +1,253 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源组集合。 + /// + private sealed class ResourceGroupCollection : IResourceGroupCollection + { + private readonly ResourceGroup[] m_ResourceGroups; + private readonly Dictionary m_ResourceInfos; + private readonly HashSet m_ResourceNames; + private long m_TotalLength; + private long m_TotalCompressedLength; + + /// + /// 初始化资源组集合的新实例。 + /// + /// 资源组集合。 + /// 资源信息引用。 + public ResourceGroupCollection(ResourceGroup[] resourceGroups, Dictionary resourceInfos) + { + if (resourceGroups == null || resourceGroups.Length < 1) + { + throw new GameFrameworkException("Resource groups is invalid."); + } + + if (resourceInfos == null) + { + throw new GameFrameworkException("Resource infos is invalid."); + } + + int lastIndex = resourceGroups.Length - 1; + for (int i = 0; i < lastIndex; i++) + { + if (resourceGroups[i] == null) + { + throw new GameFrameworkException(Utility.Text.Format("Resource group index '{0}' is invalid.", i)); + } + + for (int j = i + 1; j < resourceGroups.Length; j++) + { + if (resourceGroups[i] == resourceGroups[j]) + { + throw new GameFrameworkException(Utility.Text.Format("Resource group '{0}' duplicated.", resourceGroups[i].Name)); + } + } + } + + if (resourceGroups[lastIndex] == null) + { + throw new GameFrameworkException(Utility.Text.Format("Resource group index '{0}' is invalid.", lastIndex)); + } + + m_ResourceGroups = resourceGroups; + m_ResourceInfos = resourceInfos; + m_ResourceNames = new HashSet(); + m_TotalLength = 0L; + m_TotalCompressedLength = 0L; + + List cachedResourceNames = new List(); + foreach (ResourceGroup resourceGroup in m_ResourceGroups) + { + resourceGroup.InternalGetResourceNames(cachedResourceNames); + foreach (ResourceName resourceName in cachedResourceNames) + { + ResourceInfo resourceInfo = null; + if (!m_ResourceInfos.TryGetValue(resourceName, out resourceInfo)) + { + throw new GameFrameworkException(Utility.Text.Format("Resource info '{0}' is invalid.", resourceName.FullName)); + } + + if (m_ResourceNames.Add(resourceName)) + { + m_TotalLength += resourceInfo.Length; + m_TotalCompressedLength += resourceInfo.CompressedLength; + } + } + } + } + + /// + /// 获取资源组集合是否准备完毕。 + /// + public bool Ready + { + get + { + return ReadyCount >= TotalCount; + } + } + + /// + /// 获取资源组集合包含资源数量。 + /// + public int TotalCount + { + get + { + return m_ResourceNames.Count; + } + } + + /// + /// 获取资源组集合中已准备完成资源数量。 + /// + public int ReadyCount + { + get + { + int readyCount = 0; + foreach (ResourceName resourceName in m_ResourceNames) + { + ResourceInfo resourceInfo = null; + if (m_ResourceInfos.TryGetValue(resourceName, out resourceInfo) && resourceInfo.Ready) + { + readyCount++; + } + } + + return readyCount; + } + } + + /// + /// 获取资源组集合包含资源的总大小。 + /// + public long TotalLength + { + get + { + return m_TotalLength; + } + } + + /// + /// 获取资源组集合包含资源压缩后的总大小。 + /// + public long TotalCompressedLength + { + get + { + return m_TotalCompressedLength; + } + } + + /// + /// 获取资源组集合中已准备完成资源的总大小。 + /// + public long ReadyLength + { + get + { + long readyLength = 0L; + foreach (ResourceName resourceName in m_ResourceNames) + { + ResourceInfo resourceInfo = null; + if (m_ResourceInfos.TryGetValue(resourceName, out resourceInfo) && resourceInfo.Ready) + { + readyLength += resourceInfo.Length; + } + } + + return readyLength; + } + } + + /// + /// 获取资源组集合中已准备完成资源压缩后的总大小。 + /// + public long ReadyCompressedLength + { + get + { + long readyCompressedLength = 0L; + foreach (ResourceName resourceName in m_ResourceNames) + { + ResourceInfo resourceInfo = null; + if (m_ResourceInfos.TryGetValue(resourceName, out resourceInfo) && resourceInfo.Ready) + { + readyCompressedLength += resourceInfo.CompressedLength; + } + } + + return readyCompressedLength; + } + } + + /// + /// 获取资源组集合的完成进度。 + /// + public float Progress + { + get + { + return m_TotalLength > 0L ? (float)ReadyLength / m_TotalLength : 1f; + } + } + + /// + /// 获取资源组集合包含的资源组列表。 + /// + /// 资源组包含的资源名称列表。 + public IResourceGroup[] GetResourceGroups() + { + return m_ResourceGroups; + } + + /// + /// 获取资源组集合包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + public string[] GetResourceNames() + { + int index = 0; + string[] resourceNames = new string[m_ResourceNames.Count]; + foreach (ResourceName resourceName in m_ResourceNames) + { + resourceNames[index++] = resourceName.FullName; + } + + return resourceNames; + } + + /// + /// 获取资源组集合包含的资源名称列表。 + /// + /// 资源组包含的资源名称列表。 + public void GetResourceNames(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (ResourceName resourceName in m_ResourceNames) + { + results.Add(resourceName.FullName); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroupCollection.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroupCollection.cs.meta new file mode 100644 index 0000000..ef570e0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceGroupCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9e85d4a75b6cb64fb90f951a1bdc177 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceInfo.cs new file mode 100644 index 0000000..170d572 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceInfo.cs @@ -0,0 +1,168 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源信息。 + /// + private sealed class ResourceInfo + { + private readonly ResourceName m_ResourceName; + private readonly string m_FileSystemName; + private readonly LoadType m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly int m_CompressedLength; + private readonly bool m_StorageInReadOnly; + private bool m_Ready; + + /// + /// 初始化资源信息的新实例。 + /// + /// 资源名称。 + /// 文件系统名称。 + /// 资源加载方式。 + /// 资源大小。 + /// 资源哈希值。 + /// 压缩后资源大小。 + /// 资源是否在只读区。 + /// 资源是否准备完毕。 + public ResourceInfo(ResourceName resourceName, string fileSystemName, LoadType loadType, int length, int hashCode, int compressedLength, bool storageInReadOnly, bool ready) + { + m_ResourceName = resourceName; + m_FileSystemName = fileSystemName; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + m_CompressedLength = compressedLength; + m_StorageInReadOnly = storageInReadOnly; + m_Ready = ready; + } + + /// + /// 获取资源名称。 + /// + public ResourceName ResourceName + { + get + { + return m_ResourceName; + } + } + + /// + /// 获取资源是否使用文件系统。 + /// + public bool UseFileSystem + { + get + { + return !string.IsNullOrEmpty(m_FileSystemName); + } + } + + /// + /// 获取文件系统名称。 + /// + public string FileSystemName + { + get + { + return m_FileSystemName; + } + } + + /// + /// 获取资源是否通过二进制方式加载。 + /// + public bool IsLoadFromBinary + { + get + { + return m_LoadType == LoadType.LoadFromBinary || m_LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || m_LoadType == LoadType.LoadFromBinaryAndDecrypt; + } + } + + /// + /// 获取资源加载方式。 + /// + public LoadType LoadType + { + get + { + return m_LoadType; + } + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get + { + return m_Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_HashCode; + } + } + + /// + /// 获取压缩后资源大小。 + /// + public int CompressedLength + { + get + { + return m_CompressedLength; + } + } + + /// + /// 获取资源是否在只读区。 + /// + public bool StorageInReadOnly + { + get + { + return m_StorageInReadOnly; + } + } + + /// + /// 获取资源是否准备完毕。 + /// + public bool Ready + { + get + { + return m_Ready; + } + } + + /// + /// 标记资源准备完毕。 + /// + public void MarkReady() + { + m_Ready = true; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceInfo.cs.meta new file mode 100644 index 0000000..e883907 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1bd3f1447b6bd5549afc881a2c9d3f7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceIniter.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceIniter.cs new file mode 100644 index 0000000..0a89778 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceIniter.cs @@ -0,0 +1,181 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源初始化器。 + /// + private sealed class ResourceIniter + { + private readonly ResourceManager m_ResourceManager; + private readonly Dictionary m_CachedFileSystemNames; + private string m_CurrentVariant; + + public GameFrameworkAction ResourceInitComplete; + + /// + /// 初始化资源初始化器的新实例。 + /// + /// 资源管理器。 + public ResourceIniter(ResourceManager resourceManager) + { + m_ResourceManager = resourceManager; + m_CachedFileSystemNames = new Dictionary(); + m_CurrentVariant = null; + + ResourceInitComplete = null; + } + + /// + /// 关闭并清理资源初始化器。 + /// + public void Shutdown() + { + } + + /// + /// 初始化资源。 + /// + public void InitResources(string currentVariant) + { + m_CurrentVariant = currentVariant; + + if (m_ResourceManager.m_ResourceHelper == null) + { + throw new GameFrameworkException("Resource helper is invalid."); + } + + if (string.IsNullOrEmpty(m_ResourceManager.m_ReadOnlyPath)) + { + throw new GameFrameworkException("Read-only path is invalid."); + } + + m_ResourceManager.m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_ReadOnlyPath, RemoteVersionListFileName)), new LoadBytesCallbacks(OnLoadPackageVersionListSuccess, OnLoadPackageVersionListFailure), null); + } + + private void OnLoadPackageVersionListSuccess(string fileUri, byte[] bytes, float duration, object userData) + { + MemoryStream memoryStream = null; + try + { + memoryStream = new MemoryStream(bytes, false); + PackageVersionList versionList = m_ResourceManager.m_PackageVersionListSerializer.Deserialize(memoryStream); + if (!versionList.IsValid) + { + throw new GameFrameworkException("Deserialize package version list failure."); + } + + PackageVersionList.Asset[] assets = versionList.GetAssets(); + PackageVersionList.Resource[] resources = versionList.GetResources(); + PackageVersionList.FileSystem[] fileSystems = versionList.GetFileSystems(); + PackageVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); + m_ResourceManager.m_ApplicableGameVersion = versionList.ApplicableGameVersion; + m_ResourceManager.m_InternalResourceVersion = versionList.InternalResourceVersion; + m_ResourceManager.m_AssetInfos = new Dictionary(assets.Length, StringComparer.Ordinal); + m_ResourceManager.m_ResourceInfos = new Dictionary(resources.Length, new ResourceNameComparer()); + ResourceGroup defaultResourceGroup = m_ResourceManager.GetOrAddResourceGroup(string.Empty); + + foreach (PackageVersionList.FileSystem fileSystem in fileSystems) + { + int[] resourceIndexes = fileSystem.GetResourceIndexes(); + foreach (int resourceIndex in resourceIndexes) + { + PackageVersionList.Resource resource = resources[resourceIndex]; + if (resource.Variant != null && resource.Variant != m_CurrentVariant) + { + continue; + } + + m_CachedFileSystemNames.Add(new ResourceName(resource.Name, resource.Variant, resource.Extension), fileSystem.Name); + } + } + + foreach (PackageVersionList.Resource resource in resources) + { + if (resource.Variant != null && resource.Variant != m_CurrentVariant) + { + continue; + } + + ResourceName resourceName = new ResourceName(resource.Name, resource.Variant, resource.Extension); + int[] assetIndexes = resource.GetAssetIndexes(); + foreach (int assetIndex in assetIndexes) + { + PackageVersionList.Asset asset = assets[assetIndex]; + int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); + int index = 0; + string[] dependencyAssetNames = new string[dependencyAssetIndexes.Length]; + foreach (int dependencyAssetIndex in dependencyAssetIndexes) + { + dependencyAssetNames[index++] = assets[dependencyAssetIndex].Name; + } + + m_ResourceManager.m_AssetInfos.Add(asset.Name, new AssetInfo(asset.Name, resourceName, dependencyAssetNames)); + } + + string fileSystemName = null; + if (!m_CachedFileSystemNames.TryGetValue(resourceName, out fileSystemName)) + { + fileSystemName = null; + } + + m_ResourceManager.m_ResourceInfos.Add(resourceName, new ResourceInfo(resourceName, fileSystemName, (LoadType)resource.LoadType, resource.Length, resource.HashCode, resource.Length, true, true)); + defaultResourceGroup.AddResource(resourceName, resource.Length, resource.Length); + } + + foreach (PackageVersionList.ResourceGroup resourceGroup in resourceGroups) + { + ResourceGroup group = m_ResourceManager.GetOrAddResourceGroup(resourceGroup.Name); + int[] resourceIndexes = resourceGroup.GetResourceIndexes(); + foreach (int resourceIndex in resourceIndexes) + { + PackageVersionList.Resource resource = resources[resourceIndex]; + if (resource.Variant != null && resource.Variant != m_CurrentVariant) + { + continue; + } + + group.AddResource(new ResourceName(resource.Name, resource.Variant, resource.Extension), resource.Length, resource.Length); + } + } + + ResourceInitComplete(); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Parse package version list exception '{0}'.", exception), exception); + } + finally + { + m_CachedFileSystemNames.Clear(); + if (memoryStream != null) + { + memoryStream.Dispose(); + memoryStream = null; + } + } + } + + private void OnLoadPackageVersionListFailure(string fileUri, string errorMessage, object userData) + { + throw new GameFrameworkException(Utility.Text.Format("Package version list '{0}' is invalid, error message is '{1}'.", fileUri, string.IsNullOrEmpty(errorMessage) ? "" : errorMessage)); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceIniter.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceIniter.cs.meta new file mode 100644 index 0000000..dd77eac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceIniter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5fd705b05ce15e24daa1b8c1cdf23f59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs new file mode 100644 index 0000000..695779a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs @@ -0,0 +1,141 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceLoader + { + /// + /// 资源对象。 + /// + private sealed class AssetObject : ObjectBase + { + private List m_DependencyAssets; + private object m_Resource; + private IResourceHelper m_ResourceHelper; + private ResourceLoader m_ResourceLoader; + + public AssetObject() + { + m_DependencyAssets = new List(); + m_Resource = null; + m_ResourceHelper = null; + m_ResourceLoader = null; + } + + public override bool CustomCanReleaseFlag + { + get + { + int targetReferenceCount = 0; + m_ResourceLoader.m_AssetDependencyCount.TryGetValue(Target, out targetReferenceCount); + return base.CustomCanReleaseFlag && targetReferenceCount <= 0; + } + } + + public static AssetObject Create(string name, object target, List dependencyAssets, object resource, IResourceHelper resourceHelper, ResourceLoader resourceLoader) + { + if (dependencyAssets == null) + { + throw new GameFrameworkException("Dependency assets is invalid."); + } + + if (resource == null) + { + throw new GameFrameworkException("Resource is invalid."); + } + + if (resourceHelper == null) + { + throw new GameFrameworkException("Resource helper is invalid."); + } + + if (resourceLoader == null) + { + throw new GameFrameworkException("Resource loader is invalid."); + } + + AssetObject assetObject = ReferencePool.Acquire(); + assetObject.Initialize(name, target); + assetObject.m_DependencyAssets.AddRange(dependencyAssets); + assetObject.m_Resource = resource; + assetObject.m_ResourceHelper = resourceHelper; + assetObject.m_ResourceLoader = resourceLoader; + + foreach (object dependencyAsset in dependencyAssets) + { + int referenceCount = 0; + if (resourceLoader.m_AssetDependencyCount.TryGetValue(dependencyAsset, out referenceCount)) + { + resourceLoader.m_AssetDependencyCount[dependencyAsset] = referenceCount + 1; + } + else + { + resourceLoader.m_AssetDependencyCount.Add(dependencyAsset, 1); + } + } + + return assetObject; + } + + public override void Clear() + { + base.Clear(); + m_DependencyAssets.Clear(); + m_Resource = null; + m_ResourceHelper = null; + m_ResourceLoader = null; + } + + protected internal override void OnUnspawn() + { + base.OnUnspawn(); + foreach (object dependencyAsset in m_DependencyAssets) + { + m_ResourceLoader.m_AssetPool.Unspawn(dependencyAsset); + } + } + + protected internal override void Release(bool isShutdown) + { + if (!isShutdown) + { + int targetReferenceCount = 0; + if (m_ResourceLoader.m_AssetDependencyCount.TryGetValue(Target, out targetReferenceCount) && targetReferenceCount > 0) + { + throw new GameFrameworkException(Utility.Text.Format("Asset target '{0}' reference count is '{1}' larger than 0.", Name, targetReferenceCount)); + } + + foreach (object dependencyAsset in m_DependencyAssets) + { + int referenceCount = 0; + if (m_ResourceLoader.m_AssetDependencyCount.TryGetValue(dependencyAsset, out referenceCount)) + { + m_ResourceLoader.m_AssetDependencyCount[dependencyAsset] = referenceCount - 1; + } + else + { + throw new GameFrameworkException(Utility.Text.Format("Asset target '{0}' dependency asset reference count is invalid.", Name)); + } + } + + m_ResourceLoader.m_ResourcePool.Unspawn(m_Resource); + } + + m_ResourceLoader.m_AssetDependencyCount.Remove(Target); + m_ResourceLoader.m_AssetToResourceMap.Remove(Target); + m_ResourceHelper.Release(Target); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs.meta new file mode 100644 index 0000000..2e99e77 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e0afab98077ac34e8799708dfa2da93 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadAssetTask.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadAssetTask.cs new file mode 100644 index 0000000..ffc66be --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadAssetTask.cs @@ -0,0 +1,88 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceLoader + { + private sealed class LoadAssetTask : LoadResourceTaskBase + { + private LoadAssetCallbacks m_LoadAssetCallbacks; + + public LoadAssetTask() + { + m_LoadAssetCallbacks = null; + } + + public override bool IsScene + { + get + { + return false; + } + } + + public static LoadAssetTask Create(string assetName, Type assetType, int priority, ResourceInfo resourceInfo, string[] dependencyAssetNames, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + LoadAssetTask loadAssetTask = ReferencePool.Acquire(); + loadAssetTask.Initialize(assetName, assetType, priority, resourceInfo, dependencyAssetNames, userData); + loadAssetTask.m_LoadAssetCallbacks = loadAssetCallbacks; + return loadAssetTask; + } + + public override void Clear() + { + base.Clear(); + m_LoadAssetCallbacks = null; + } + + public override void OnLoadAssetSuccess(LoadResourceAgent agent, object asset, float duration) + { + base.OnLoadAssetSuccess(agent, asset, duration); + if (m_LoadAssetCallbacks.LoadAssetSuccessCallback != null) + { + m_LoadAssetCallbacks.LoadAssetSuccessCallback(AssetName, asset, duration, UserData); + } + } + + public override void OnLoadAssetFailure(LoadResourceAgent agent, LoadResourceStatus status, string errorMessage) + { + base.OnLoadAssetFailure(agent, status, errorMessage); + if (m_LoadAssetCallbacks.LoadAssetFailureCallback != null) + { + m_LoadAssetCallbacks.LoadAssetFailureCallback(AssetName, status, errorMessage, UserData); + } + } + + public override void OnLoadAssetUpdate(LoadResourceAgent agent, LoadResourceProgress type, float progress) + { + base.OnLoadAssetUpdate(agent, type, progress); + if (type == LoadResourceProgress.LoadAsset) + { + if (m_LoadAssetCallbacks.LoadAssetUpdateCallback != null) + { + m_LoadAssetCallbacks.LoadAssetUpdateCallback(AssetName, progress, UserData); + } + } + } + + public override void OnLoadDependencyAsset(LoadResourceAgent agent, string dependencyAssetName, object dependencyAsset) + { + base.OnLoadDependencyAsset(agent, dependencyAssetName, dependencyAsset); + if (m_LoadAssetCallbacks.LoadAssetDependencyAssetCallback != null) + { + m_LoadAssetCallbacks.LoadAssetDependencyAssetCallback(AssetName, dependencyAssetName, LoadedDependencyAssetCount, TotalDependencyAssetCount, UserData); + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadAssetTask.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadAssetTask.cs.meta new file mode 100644 index 0000000..28f283b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadAssetTask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14f7ed0057d8d654d9ef3c9613aa962e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadBinaryInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadBinaryInfo.cs new file mode 100644 index 0000000..45657b0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadBinaryInfo.cs @@ -0,0 +1,81 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceLoader + { + private sealed class LoadBinaryInfo : IReference + { + private string m_BinaryAssetName; + private ResourceInfo m_ResourceInfo; + private LoadBinaryCallbacks m_LoadBinaryCallbacks; + private object m_UserData; + + public LoadBinaryInfo() + { + m_BinaryAssetName = null; + m_ResourceInfo = null; + m_LoadBinaryCallbacks = null; + m_UserData = null; + } + + public string BinaryAssetName + { + get + { + return m_BinaryAssetName; + } + } + + public ResourceInfo ResourceInfo + { + get + { + return m_ResourceInfo; + } + } + + public LoadBinaryCallbacks LoadBinaryCallbacks + { + get + { + return m_LoadBinaryCallbacks; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + + public static LoadBinaryInfo Create(string binaryAssetName, ResourceInfo resourceInfo, LoadBinaryCallbacks loadBinaryCallbacks, object userData) + { + LoadBinaryInfo loadBinaryInfo = ReferencePool.Acquire(); + loadBinaryInfo.m_BinaryAssetName = binaryAssetName; + loadBinaryInfo.m_ResourceInfo = resourceInfo; + loadBinaryInfo.m_LoadBinaryCallbacks = loadBinaryCallbacks; + loadBinaryInfo.m_UserData = userData; + return loadBinaryInfo; + } + + public void Clear() + { + m_BinaryAssetName = null; + m_ResourceInfo = null; + m_LoadBinaryCallbacks = null; + m_UserData = null; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadBinaryInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadBinaryInfo.cs.meta new file mode 100644 index 0000000..e0e0a8b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadBinaryInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c9df77cd883d4f49a99773a27b3a32c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadDependencyAssetTask.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadDependencyAssetTask.cs new file mode 100644 index 0000000..6da2e63 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadDependencyAssetTask.cs @@ -0,0 +1,60 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceLoader + { + private sealed class LoadDependencyAssetTask : LoadResourceTaskBase + { + private LoadResourceTaskBase m_MainTask; + + public LoadDependencyAssetTask() + { + m_MainTask = null; + } + + public override bool IsScene + { + get + { + return false; + } + } + + public static LoadDependencyAssetTask Create(string assetName, int priority, ResourceInfo resourceInfo, string[] dependencyAssetNames, LoadResourceTaskBase mainTask, object userData) + { + LoadDependencyAssetTask loadDependencyAssetTask = ReferencePool.Acquire(); + loadDependencyAssetTask.Initialize(assetName, null, priority, resourceInfo, dependencyAssetNames, userData); + loadDependencyAssetTask.m_MainTask = mainTask; + loadDependencyAssetTask.m_MainTask.TotalDependencyAssetCount++; + return loadDependencyAssetTask; + } + + public override void Clear() + { + base.Clear(); + m_MainTask = null; + } + + public override void OnLoadAssetSuccess(LoadResourceAgent agent, object asset, float duration) + { + base.OnLoadAssetSuccess(agent, asset, duration); + m_MainTask.OnLoadDependencyAsset(agent, AssetName, asset); + } + + public override void OnLoadAssetFailure(LoadResourceAgent agent, LoadResourceStatus status, string errorMessage) + { + base.OnLoadAssetFailure(agent, status, errorMessage); + m_MainTask.OnLoadAssetFailure(agent, LoadResourceStatus.DependencyError, Utility.Text.Format("Can not load dependency asset '{0}', internal status '{1}', internal error message '{2}'.", AssetName, status, errorMessage)); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadDependencyAssetTask.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadDependencyAssetTask.cs.meta new file mode 100644 index 0000000..9ff26a8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadDependencyAssetTask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41fd3dadaf0c458499d8bf6fb4d88e63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs new file mode 100644 index 0000000..f7d340f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs @@ -0,0 +1,361 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; +using System; +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceLoader + { + /// + /// 加载资源代理。 + /// + private sealed partial class LoadResourceAgent : ITaskAgent + { + private static readonly Dictionary s_CachedResourceNames = new Dictionary(StringComparer.Ordinal); + private static readonly HashSet s_LoadingAssetNames = new HashSet(StringComparer.Ordinal); + private static readonly HashSet s_LoadingResourceNames = new HashSet(StringComparer.Ordinal); + + private readonly ILoadResourceAgentHelper m_Helper; + private readonly IResourceHelper m_ResourceHelper; + private readonly ResourceLoader m_ResourceLoader; + private readonly string m_ReadOnlyPath; + private readonly string m_ReadWritePath; + private readonly DecryptResourceCallback m_DecryptResourceCallback; + private LoadResourceTaskBase m_Task; + + /// + /// 初始化加载资源代理的新实例。 + /// + /// 加载资源代理辅助器。 + /// 资源辅助器。 + /// 加载资源器。 + /// 资源只读区路径。 + /// 资源读写区路径。 + /// 解密资源回调函数。 + public LoadResourceAgent(ILoadResourceAgentHelper loadResourceAgentHelper, IResourceHelper resourceHelper, ResourceLoader resourceLoader, string readOnlyPath, string readWritePath, DecryptResourceCallback decryptResourceCallback) + { + if (loadResourceAgentHelper == null) + { + throw new GameFrameworkException("Load resource agent helper is invalid."); + } + + if (resourceHelper == null) + { + throw new GameFrameworkException("Resource helper is invalid."); + } + + if (resourceLoader == null) + { + throw new GameFrameworkException("Resource loader is invalid."); + } + + if (decryptResourceCallback == null) + { + throw new GameFrameworkException("Decrypt resource callback is invalid."); + } + + m_Helper = loadResourceAgentHelper; + m_ResourceHelper = resourceHelper; + m_ResourceLoader = resourceLoader; + m_ReadOnlyPath = readOnlyPath; + m_ReadWritePath = readWritePath; + m_DecryptResourceCallback = decryptResourceCallback; + m_Task = null; + } + + public ILoadResourceAgentHelper Helper + { + get + { + return m_Helper; + } + } + + /// + /// 获取加载资源任务。 + /// + public LoadResourceTaskBase Task + { + get + { + return m_Task; + } + } + + /// + /// 初始化加载资源代理。 + /// + public void Initialize() + { + m_Helper.LoadResourceAgentHelperUpdate += OnLoadResourceAgentHelperUpdate; + m_Helper.LoadResourceAgentHelperReadFileComplete += OnLoadResourceAgentHelperReadFileComplete; + m_Helper.LoadResourceAgentHelperReadBytesComplete += OnLoadResourceAgentHelperReadBytesComplete; + m_Helper.LoadResourceAgentHelperParseBytesComplete += OnLoadResourceAgentHelperParseBytesComplete; + m_Helper.LoadResourceAgentHelperLoadComplete += OnLoadResourceAgentHelperLoadComplete; + m_Helper.LoadResourceAgentHelperError += OnLoadResourceAgentHelperError; + } + + /// + /// 加载资源代理轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理加载资源代理。 + /// + public void Shutdown() + { + Reset(); + m_Helper.LoadResourceAgentHelperUpdate -= OnLoadResourceAgentHelperUpdate; + m_Helper.LoadResourceAgentHelperReadFileComplete -= OnLoadResourceAgentHelperReadFileComplete; + m_Helper.LoadResourceAgentHelperReadBytesComplete -= OnLoadResourceAgentHelperReadBytesComplete; + m_Helper.LoadResourceAgentHelperParseBytesComplete -= OnLoadResourceAgentHelperParseBytesComplete; + m_Helper.LoadResourceAgentHelperLoadComplete -= OnLoadResourceAgentHelperLoadComplete; + m_Helper.LoadResourceAgentHelperError -= OnLoadResourceAgentHelperError; + } + + public static void Clear() + { + s_CachedResourceNames.Clear(); + s_LoadingAssetNames.Clear(); + s_LoadingResourceNames.Clear(); + } + + /// + /// 开始处理加载资源任务。 + /// + /// 要处理的加载资源任务。 + /// 开始处理任务的状态。 + public StartTaskStatus Start(LoadResourceTaskBase task) + { + if (task == null) + { + throw new GameFrameworkException("Task is invalid."); + } + + m_Task = task; + m_Task.StartTime = DateTime.UtcNow; + ResourceInfo resourceInfo = m_Task.ResourceInfo; + + if (!resourceInfo.Ready) + { + m_Task.StartTime = default(DateTime); + return StartTaskStatus.HasToWait; + } + + if (IsAssetLoading(m_Task.AssetName)) + { + m_Task.StartTime = default(DateTime); + return StartTaskStatus.HasToWait; + } + + if (!m_Task.IsScene) + { + AssetObject assetObject = m_ResourceLoader.m_AssetPool.Spawn(m_Task.AssetName); + if (assetObject != null) + { + OnAssetObjectReady(assetObject); + return StartTaskStatus.Done; + } + } + + foreach (string dependencyAssetName in m_Task.GetDependencyAssetNames()) + { + if (!m_ResourceLoader.m_AssetPool.CanSpawn(dependencyAssetName)) + { + m_Task.StartTime = default(DateTime); + return StartTaskStatus.HasToWait; + } + } + + string resourceName = resourceInfo.ResourceName.Name; + if (IsResourceLoading(resourceName)) + { + m_Task.StartTime = default(DateTime); + return StartTaskStatus.HasToWait; + } + + s_LoadingAssetNames.Add(m_Task.AssetName); + + ResourceObject resourceObject = m_ResourceLoader.m_ResourcePool.Spawn(resourceName); + if (resourceObject != null) + { + OnResourceObjectReady(resourceObject); + return StartTaskStatus.CanResume; + } + + s_LoadingResourceNames.Add(resourceName); + + string fullPath = null; + if (!s_CachedResourceNames.TryGetValue(resourceName, out fullPath)) + { + fullPath = Utility.Path.GetRegularPath(Path.Combine(resourceInfo.StorageInReadOnly ? m_ReadOnlyPath : m_ReadWritePath, resourceInfo.UseFileSystem ? resourceInfo.FileSystemName : resourceInfo.ResourceName.FullName)); + s_CachedResourceNames.Add(resourceName, fullPath); + } + + if (resourceInfo.LoadType == LoadType.LoadFromFile) + { + if (resourceInfo.UseFileSystem) + { + IFileSystem fileSystem = m_ResourceLoader.m_ResourceManager.GetFileSystem(resourceInfo.FileSystemName, resourceInfo.StorageInReadOnly); + m_Helper.ReadFile(fileSystem, resourceInfo.ResourceName.FullName); + } + else + { + m_Helper.ReadFile(fullPath); + } + } + else if (resourceInfo.LoadType == LoadType.LoadFromMemory || resourceInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || resourceInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt) + { + if (resourceInfo.UseFileSystem) + { + IFileSystem fileSystem = m_ResourceLoader.m_ResourceManager.GetFileSystem(resourceInfo.FileSystemName, resourceInfo.StorageInReadOnly); + m_Helper.ReadBytes(fileSystem, resourceInfo.ResourceName.FullName); + } + else + { + m_Helper.ReadBytes(fullPath); + } + } + else + { + throw new GameFrameworkException(Utility.Text.Format("Resource load type '{0}' is not supported.", resourceInfo.LoadType)); + } + + return StartTaskStatus.CanResume; + } + + /// + /// 重置加载资源代理。 + /// + public void Reset() + { + m_Helper.Reset(); + m_Task = null; + } + + private static bool IsAssetLoading(string assetName) + { + return s_LoadingAssetNames.Contains(assetName); + } + + private static bool IsResourceLoading(string resourceName) + { + return s_LoadingResourceNames.Contains(resourceName); + } + + private void OnAssetObjectReady(AssetObject assetObject) + { + m_Helper.Reset(); + + object asset = assetObject.Target; + if (m_Task.IsScene) + { + m_ResourceLoader.m_SceneToAssetMap.Add(m_Task.AssetName, asset); + } + + m_Task.OnLoadAssetSuccess(this, asset, (float)(DateTime.UtcNow - m_Task.StartTime).TotalSeconds); + m_Task.Done = true; + } + + private void OnResourceObjectReady(ResourceObject resourceObject) + { + m_Task.LoadMain(this, resourceObject); + } + + private void OnError(LoadResourceStatus status, string errorMessage) + { + m_Helper.Reset(); + m_Task.OnLoadAssetFailure(this, status, errorMessage); + s_LoadingAssetNames.Remove(m_Task.AssetName); + s_LoadingResourceNames.Remove(m_Task.ResourceInfo.ResourceName.Name); + m_Task.Done = true; + } + + private void OnLoadResourceAgentHelperUpdate(object sender, LoadResourceAgentHelperUpdateEventArgs e) + { + m_Task.OnLoadAssetUpdate(this, e.Type, e.Progress); + } + + private void OnLoadResourceAgentHelperReadFileComplete(object sender, LoadResourceAgentHelperReadFileCompleteEventArgs e) + { + ResourceObject resourceObject = ResourceObject.Create(m_Task.ResourceInfo.ResourceName.Name, e.Resource, m_ResourceHelper, m_ResourceLoader); + m_ResourceLoader.m_ResourcePool.Register(resourceObject, true); + s_LoadingResourceNames.Remove(m_Task.ResourceInfo.ResourceName.Name); + OnResourceObjectReady(resourceObject); + } + + private void OnLoadResourceAgentHelperReadBytesComplete(object sender, LoadResourceAgentHelperReadBytesCompleteEventArgs e) + { + byte[] bytes = e.GetBytes(); + ResourceInfo resourceInfo = m_Task.ResourceInfo; + if (resourceInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || resourceInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt) + { + m_DecryptResourceCallback(bytes, 0, bytes.Length, resourceInfo.ResourceName.Name, resourceInfo.ResourceName.Variant, resourceInfo.ResourceName.Extension, resourceInfo.StorageInReadOnly, resourceInfo.FileSystemName, (byte)resourceInfo.LoadType, resourceInfo.Length, resourceInfo.HashCode); + } + + m_Helper.ParseBytes(bytes); + } + + private void OnLoadResourceAgentHelperParseBytesComplete(object sender, LoadResourceAgentHelperParseBytesCompleteEventArgs e) + { + ResourceObject resourceObject = ResourceObject.Create(m_Task.ResourceInfo.ResourceName.Name, e.Resource, m_ResourceHelper, m_ResourceLoader); + m_ResourceLoader.m_ResourcePool.Register(resourceObject, true); + s_LoadingResourceNames.Remove(m_Task.ResourceInfo.ResourceName.Name); + OnResourceObjectReady(resourceObject); + } + + private void OnLoadResourceAgentHelperLoadComplete(object sender, LoadResourceAgentHelperLoadCompleteEventArgs e) + { + AssetObject assetObject = null; + if (m_Task.IsScene) + { + assetObject = m_ResourceLoader.m_AssetPool.Spawn(m_Task.AssetName); + } + + if (assetObject == null) + { + List dependencyAssets = m_Task.GetDependencyAssets(); + assetObject = AssetObject.Create(m_Task.AssetName, e.Asset, dependencyAssets, m_Task.ResourceObject.Target, m_ResourceHelper, m_ResourceLoader); + m_ResourceLoader.m_AssetPool.Register(assetObject, true); + m_ResourceLoader.m_AssetToResourceMap.Add(e.Asset, m_Task.ResourceObject.Target); + foreach (object dependencyAsset in dependencyAssets) + { + object dependencyResource = null; + if (m_ResourceLoader.m_AssetToResourceMap.TryGetValue(dependencyAsset, out dependencyResource)) + { + m_Task.ResourceObject.AddDependencyResource(dependencyResource); + } + else + { + throw new GameFrameworkException("Can not find dependency resource."); + } + } + } + + s_LoadingAssetNames.Remove(m_Task.AssetName); + OnAssetObjectReady(assetObject); + } + + private void OnLoadResourceAgentHelperError(object sender, LoadResourceAgentHelperErrorEventArgs e) + { + OnError(e.Status, e.ErrorMessage); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs.meta new file mode 100644 index 0000000..e49e493 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ce574a2d7f6ce54d9bf8c542a7c8953 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceTaskBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceTaskBase.cs new file mode 100644 index 0000000..b371f1e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceTaskBase.cs @@ -0,0 +1,176 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceLoader + { + private abstract class LoadResourceTaskBase : TaskBase + { + private static int s_Serial = 0; + + private string m_AssetName; + private Type m_AssetType; + private ResourceInfo m_ResourceInfo; + private string[] m_DependencyAssetNames; + private readonly List m_DependencyAssets; + private ResourceObject m_ResourceObject; + private DateTime m_StartTime; + private int m_TotalDependencyAssetCount; + + public LoadResourceTaskBase() + { + m_AssetName = null; + m_AssetType = null; + m_ResourceInfo = null; + m_DependencyAssetNames = null; + m_DependencyAssets = new List(); + m_ResourceObject = null; + m_StartTime = default(DateTime); + m_TotalDependencyAssetCount = 0; + } + + public string AssetName + { + get + { + return m_AssetName; + } + } + + public Type AssetType + { + get + { + return m_AssetType; + } + } + + public ResourceInfo ResourceInfo + { + get + { + return m_ResourceInfo; + } + } + + public ResourceObject ResourceObject + { + get + { + return m_ResourceObject; + } + } + + public abstract bool IsScene + { + get; + } + + public DateTime StartTime + { + get + { + return m_StartTime; + } + set + { + m_StartTime = value; + } + } + + public int LoadedDependencyAssetCount + { + get + { + return m_DependencyAssets.Count; + } + } + + public int TotalDependencyAssetCount + { + get + { + return m_TotalDependencyAssetCount; + } + set + { + m_TotalDependencyAssetCount = value; + } + } + + public override string Description + { + get + { + return m_AssetName; + } + } + + public override void Clear() + { + base.Clear(); + m_AssetName = null; + m_AssetType = null; + m_ResourceInfo = null; + m_DependencyAssetNames = null; + m_DependencyAssets.Clear(); + m_ResourceObject = null; + m_StartTime = default(DateTime); + m_TotalDependencyAssetCount = 0; + } + + public string[] GetDependencyAssetNames() + { + return m_DependencyAssetNames; + } + + public List GetDependencyAssets() + { + return m_DependencyAssets; + } + + public void LoadMain(LoadResourceAgent agent, ResourceObject resourceObject) + { + m_ResourceObject = resourceObject; + agent.Helper.LoadAsset(resourceObject.Target, AssetName, AssetType, IsScene); + } + + public virtual void OnLoadAssetSuccess(LoadResourceAgent agent, object asset, float duration) + { + } + + public virtual void OnLoadAssetFailure(LoadResourceAgent agent, LoadResourceStatus status, string errorMessage) + { + } + + public virtual void OnLoadAssetUpdate(LoadResourceAgent agent, LoadResourceProgress type, float progress) + { + } + + public virtual void OnLoadDependencyAsset(LoadResourceAgent agent, string dependencyAssetName, object dependencyAsset) + { + m_DependencyAssets.Add(dependencyAsset); + } + + protected void Initialize(string assetName, Type assetType, int priority, ResourceInfo resourceInfo, string[] dependencyAssetNames, object userData) + { + Initialize(++s_Serial, null, priority, userData); + m_AssetName = assetName; + m_AssetType = assetType; + m_ResourceInfo = resourceInfo; + m_DependencyAssetNames = dependencyAssetNames; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceTaskBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceTaskBase.cs.meta new file mode 100644 index 0000000..9e9381e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceTaskBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8306fa8150358e741a9c7e1f177ea2e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadSceneTask.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadSceneTask.cs new file mode 100644 index 0000000..0ed85f5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadSceneTask.cs @@ -0,0 +1,86 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceLoader + { + private sealed class LoadSceneTask : LoadResourceTaskBase + { + private LoadSceneCallbacks m_LoadSceneCallbacks; + + public LoadSceneTask() + { + m_LoadSceneCallbacks = null; + } + + public override bool IsScene + { + get + { + return true; + } + } + + public static LoadSceneTask Create(string sceneAssetName, int priority, ResourceInfo resourceInfo, string[] dependencyAssetNames, LoadSceneCallbacks loadSceneCallbacks, object userData) + { + LoadSceneTask loadSceneTask = ReferencePool.Acquire(); + loadSceneTask.Initialize(sceneAssetName, null, priority, resourceInfo, dependencyAssetNames, userData); + loadSceneTask.m_LoadSceneCallbacks = loadSceneCallbacks; + return loadSceneTask; + } + + public override void Clear() + { + base.Clear(); + m_LoadSceneCallbacks = null; + } + + public override void OnLoadAssetSuccess(LoadResourceAgent agent, object asset, float duration) + { + base.OnLoadAssetSuccess(agent, asset, duration); + if (m_LoadSceneCallbacks.LoadSceneSuccessCallback != null) + { + m_LoadSceneCallbacks.LoadSceneSuccessCallback(AssetName, duration, UserData); + } + } + + public override void OnLoadAssetFailure(LoadResourceAgent agent, LoadResourceStatus status, string errorMessage) + { + base.OnLoadAssetFailure(agent, status, errorMessage); + if (m_LoadSceneCallbacks.LoadSceneFailureCallback != null) + { + m_LoadSceneCallbacks.LoadSceneFailureCallback(AssetName, status, errorMessage, UserData); + } + } + + public override void OnLoadAssetUpdate(LoadResourceAgent agent, LoadResourceProgress type, float progress) + { + base.OnLoadAssetUpdate(agent, type, progress); + if (type == LoadResourceProgress.LoadScene) + { + if (m_LoadSceneCallbacks.LoadSceneUpdateCallback != null) + { + m_LoadSceneCallbacks.LoadSceneUpdateCallback(AssetName, progress, UserData); + } + } + } + + public override void OnLoadDependencyAsset(LoadResourceAgent agent, string dependencyAssetName, object dependencyAsset) + { + base.OnLoadDependencyAsset(agent, dependencyAssetName, dependencyAsset); + if (m_LoadSceneCallbacks.LoadSceneDependencyAssetCallback != null) + { + m_LoadSceneCallbacks.LoadSceneDependencyAssetCallback(AssetName, dependencyAssetName, LoadedDependencyAssetCount, TotalDependencyAssetCount, UserData); + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadSceneTask.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadSceneTask.cs.meta new file mode 100644 index 0000000..ba54c82 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.LoadSceneTask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3dc9da29e59fb9343907f59377c06f41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.ResourceObject.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.ResourceObject.cs new file mode 100644 index 0000000..9242566 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.ResourceObject.cs @@ -0,0 +1,125 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceLoader + { + /// + /// 资源对象。 + /// + private sealed class ResourceObject : ObjectBase + { + private List m_DependencyResources; + private IResourceHelper m_ResourceHelper; + private ResourceLoader m_ResourceLoader; + + public ResourceObject() + { + m_DependencyResources = new List(); + m_ResourceHelper = null; + m_ResourceLoader = null; + } + + public override bool CustomCanReleaseFlag + { + get + { + int targetReferenceCount = 0; + m_ResourceLoader.m_ResourceDependencyCount.TryGetValue(Target, out targetReferenceCount); + return base.CustomCanReleaseFlag && targetReferenceCount <= 0; + } + } + + public static ResourceObject Create(string name, object target, IResourceHelper resourceHelper, ResourceLoader resourceLoader) + { + if (resourceHelper == null) + { + throw new GameFrameworkException("Resource helper is invalid."); + } + + if (resourceLoader == null) + { + throw new GameFrameworkException("Resource loader is invalid."); + } + + ResourceObject resourceObject = ReferencePool.Acquire(); + resourceObject.Initialize(name, target); + resourceObject.m_ResourceHelper = resourceHelper; + resourceObject.m_ResourceLoader = resourceLoader; + return resourceObject; + } + + public override void Clear() + { + base.Clear(); + m_DependencyResources.Clear(); + m_ResourceHelper = null; + m_ResourceLoader = null; + } + + public void AddDependencyResource(object dependencyResource) + { + if (Target == dependencyResource) + { + return; + } + + if (m_DependencyResources.Contains(dependencyResource)) + { + return; + } + + m_DependencyResources.Add(dependencyResource); + + int referenceCount = 0; + if (m_ResourceLoader.m_ResourceDependencyCount.TryGetValue(dependencyResource, out referenceCount)) + { + m_ResourceLoader.m_ResourceDependencyCount[dependencyResource] = referenceCount + 1; + } + else + { + m_ResourceLoader.m_ResourceDependencyCount.Add(dependencyResource, 1); + } + } + + protected internal override void Release(bool isShutdown) + { + if (!isShutdown) + { + int targetReferenceCount = 0; + if (m_ResourceLoader.m_ResourceDependencyCount.TryGetValue(Target, out targetReferenceCount) && targetReferenceCount > 0) + { + throw new GameFrameworkException(Utility.Text.Format("Resource target '{0}' reference count is '{1}' larger than 0.", Name, targetReferenceCount)); + } + + foreach (object dependencyResource in m_DependencyResources) + { + int referenceCount = 0; + if (m_ResourceLoader.m_ResourceDependencyCount.TryGetValue(dependencyResource, out referenceCount)) + { + m_ResourceLoader.m_ResourceDependencyCount[dependencyResource] = referenceCount - 1; + } + else + { + throw new GameFrameworkException(Utility.Text.Format("Resource target '{0}' dependency asset reference count is invalid.", Name)); + } + } + } + + m_ResourceLoader.m_ResourceDependencyCount.Remove(Target); + m_ResourceHelper.Release(Target); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.ResourceObject.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.ResourceObject.cs.meta new file mode 100644 index 0000000..32d2856 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.ResourceObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 48616724889f3194daed53813ae1c35b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.cs new file mode 100644 index 0000000..4659931 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.cs @@ -0,0 +1,943 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; +using GameFramework.ObjectPool; +using System; +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 加载资源器。 + /// + private sealed partial class ResourceLoader + { + private const int CachedHashBytesLength = 4; + + private readonly ResourceManager m_ResourceManager; + private readonly TaskPool m_TaskPool; + private readonly Dictionary m_AssetDependencyCount; + private readonly Dictionary m_ResourceDependencyCount; + private readonly Dictionary m_AssetToResourceMap; + private readonly Dictionary m_SceneToAssetMap; + private readonly LoadBytesCallbacks m_LoadBytesCallbacks; + private readonly byte[] m_CachedHashBytes; + private IObjectPool m_AssetPool; + private IObjectPool m_ResourcePool; + + /// + /// 初始化加载资源器的新实例。 + /// + /// 资源管理器。 + public ResourceLoader(ResourceManager resourceManager) + { + m_ResourceManager = resourceManager; + m_TaskPool = new TaskPool(); + m_AssetDependencyCount = new Dictionary(); + m_ResourceDependencyCount = new Dictionary(); + m_AssetToResourceMap = new Dictionary(); + m_SceneToAssetMap = new Dictionary(StringComparer.Ordinal); + m_LoadBytesCallbacks = new LoadBytesCallbacks(OnLoadBinarySuccess, OnLoadBinaryFailure); + m_CachedHashBytes = new byte[CachedHashBytesLength]; + m_AssetPool = null; + m_ResourcePool = null; + } + + /// + /// 获取加载资源代理总数量。 + /// + public int TotalAgentCount + { + get + { + return m_TaskPool.TotalAgentCount; + } + } + + /// + /// 获取可用加载资源代理数量。 + /// + public int FreeAgentCount + { + get + { + return m_TaskPool.FreeAgentCount; + } + } + + /// + /// 获取工作中加载资源代理数量。 + /// + public int WorkingAgentCount + { + get + { + return m_TaskPool.WorkingAgentCount; + } + } + + /// + /// 获取等待加载资源任务数量。 + /// + public int WaitingTaskCount + { + get + { + return m_TaskPool.WaitingTaskCount; + } + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + public float AssetAutoReleaseInterval + { + get + { + return m_AssetPool.AutoReleaseInterval; + } + set + { + m_AssetPool.AutoReleaseInterval = value; + } + } + + /// + /// 获取或设置资源对象池的容量。 + /// + public int AssetCapacity + { + get + { + return m_AssetPool.Capacity; + } + set + { + m_AssetPool.Capacity = value; + } + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + public float AssetExpireTime + { + get + { + return m_AssetPool.ExpireTime; + } + set + { + m_AssetPool.ExpireTime = value; + } + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + public int AssetPriority + { + get + { + return m_AssetPool.Priority; + } + set + { + m_AssetPool.Priority = value; + } + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + public float ResourceAutoReleaseInterval + { + get + { + return m_ResourcePool.AutoReleaseInterval; + } + set + { + m_ResourcePool.AutoReleaseInterval = value; + } + } + + /// + /// 获取或设置资源对象池的容量。 + /// + public int ResourceCapacity + { + get + { + return m_ResourcePool.Capacity; + } + set + { + m_ResourcePool.Capacity = value; + } + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + public float ResourceExpireTime + { + get + { + return m_ResourcePool.ExpireTime; + } + set + { + m_ResourcePool.ExpireTime = value; + } + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + public int ResourcePriority + { + get + { + return m_ResourcePool.Priority; + } + set + { + m_ResourcePool.Priority = value; + } + } + + /// + /// 加载资源器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + m_TaskPool.Update(elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理加载资源器。 + /// + public void Shutdown() + { + m_TaskPool.Shutdown(); + m_AssetDependencyCount.Clear(); + m_ResourceDependencyCount.Clear(); + m_AssetToResourceMap.Clear(); + m_SceneToAssetMap.Clear(); + LoadResourceAgent.Clear(); + } + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + public void SetObjectPoolManager(IObjectPoolManager objectPoolManager) + { + m_AssetPool = objectPoolManager.CreateMultiSpawnObjectPool("Asset Pool"); + m_ResourcePool = objectPoolManager.CreateMultiSpawnObjectPool("Resource Pool"); + } + + /// + /// 增加加载资源代理辅助器。 + /// + /// 要增加的加载资源代理辅助器。 + /// 资源辅助器。 + /// 资源只读区路径。 + /// 资源读写区路径。 + /// 要设置的解密资源回调函数。 + public void AddLoadResourceAgentHelper(ILoadResourceAgentHelper loadResourceAgentHelper, IResourceHelper resourceHelper, string readOnlyPath, string readWritePath, DecryptResourceCallback decryptResourceCallback) + { + if (m_AssetPool == null || m_ResourcePool == null) + { + throw new GameFrameworkException("You must set object pool manager first."); + } + + LoadResourceAgent agent = new LoadResourceAgent(loadResourceAgentHelper, resourceHelper, this, readOnlyPath, readWritePath, decryptResourceCallback ?? DefaultDecryptResourceCallback); + m_TaskPool.AddAgent(agent); + } + + /// + /// 检查资源是否存在。 + /// + /// 要检查资源的名称。 + /// 检查资源是否存在的结果。 + public HasAssetResult HasAsset(string assetName) + { + ResourceInfo resourceInfo = GetResourceInfo(assetName); + if (resourceInfo == null) + { + return HasAssetResult.NotExist; + } + + if (!resourceInfo.Ready && m_ResourceManager.m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + return HasAssetResult.NotReady; + } + + if (resourceInfo.UseFileSystem) + { + return resourceInfo.IsLoadFromBinary ? HasAssetResult.BinaryOnFileSystem : HasAssetResult.AssetOnFileSystem; + } + else + { + return resourceInfo.IsLoadFromBinary ? HasAssetResult.BinaryOnDisk : HasAssetResult.AssetOnDisk; + } + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + ResourceInfo resourceInfo = null; + string[] dependencyAssetNames = null; + if (!CheckAsset(assetName, out resourceInfo, out dependencyAssetNames)) + { + string errorMessage = Utility.Text.Format("Can not load asset '{0}'.", assetName); + if (loadAssetCallbacks.LoadAssetFailureCallback != null) + { + loadAssetCallbacks.LoadAssetFailureCallback(assetName, resourceInfo != null && !resourceInfo.Ready ? LoadResourceStatus.NotReady : LoadResourceStatus.NotExist, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + if (resourceInfo.IsLoadFromBinary) + { + string errorMessage = Utility.Text.Format("Can not load asset '{0}' which is a binary asset.", assetName); + if (loadAssetCallbacks.LoadAssetFailureCallback != null) + { + loadAssetCallbacks.LoadAssetFailureCallback(assetName, LoadResourceStatus.TypeError, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + LoadAssetTask mainTask = LoadAssetTask.Create(assetName, assetType, priority, resourceInfo, dependencyAssetNames, loadAssetCallbacks, userData); + foreach (string dependencyAssetName in dependencyAssetNames) + { + if (!LoadDependencyAsset(dependencyAssetName, priority, mainTask, userData)) + { + string errorMessage = Utility.Text.Format("Can not load dependency asset '{0}' when load asset '{1}'.", dependencyAssetName, assetName); + if (loadAssetCallbacks.LoadAssetFailureCallback != null) + { + loadAssetCallbacks.LoadAssetFailureCallback(assetName, LoadResourceStatus.DependencyError, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + } + + m_TaskPool.AddTask(mainTask); + if (!resourceInfo.Ready) + { + m_ResourceManager.UpdateResource(resourceInfo.ResourceName); + } + } + + /// + /// 卸载资源。 + /// + /// 要卸载的资源。 + public void UnloadAsset(object asset) + { + m_AssetPool.Unspawn(asset); + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景资源的优先级。 + /// 加载场景回调函数集。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, int priority, LoadSceneCallbacks loadSceneCallbacks, object userData) + { + ResourceInfo resourceInfo = null; + string[] dependencyAssetNames = null; + if (!CheckAsset(sceneAssetName, out resourceInfo, out dependencyAssetNames)) + { + string errorMessage = Utility.Text.Format("Can not load scene '{0}'.", sceneAssetName); + if (loadSceneCallbacks.LoadSceneFailureCallback != null) + { + loadSceneCallbacks.LoadSceneFailureCallback(sceneAssetName, resourceInfo != null && !resourceInfo.Ready ? LoadResourceStatus.NotReady : LoadResourceStatus.NotExist, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + if (resourceInfo.IsLoadFromBinary) + { + string errorMessage = Utility.Text.Format("Can not load scene asset '{0}' which is a binary asset.", sceneAssetName); + if (loadSceneCallbacks.LoadSceneFailureCallback != null) + { + loadSceneCallbacks.LoadSceneFailureCallback(sceneAssetName, LoadResourceStatus.TypeError, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + LoadSceneTask mainTask = LoadSceneTask.Create(sceneAssetName, priority, resourceInfo, dependencyAssetNames, loadSceneCallbacks, userData); + foreach (string dependencyAssetName in dependencyAssetNames) + { + if (!LoadDependencyAsset(dependencyAssetName, priority, mainTask, userData)) + { + string errorMessage = Utility.Text.Format("Can not load dependency asset '{0}' when load scene '{1}'.", dependencyAssetName, sceneAssetName); + if (loadSceneCallbacks.LoadSceneFailureCallback != null) + { + loadSceneCallbacks.LoadSceneFailureCallback(sceneAssetName, LoadResourceStatus.DependencyError, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + } + + m_TaskPool.AddTask(mainTask); + if (!resourceInfo.Ready) + { + m_ResourceManager.UpdateResource(resourceInfo.ResourceName); + } + } + + /// + /// 异步卸载场景。 + /// + /// 要卸载场景资源的名称。 + /// 卸载场景回调函数集。 + /// 用户自定义数据。 + public void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData) + { + if (m_ResourceManager.m_ResourceHelper == null) + { + throw new GameFrameworkException("You must set resource helper first."); + } + + object asset = null; + if (m_SceneToAssetMap.TryGetValue(sceneAssetName, out asset)) + { + m_SceneToAssetMap.Remove(sceneAssetName); + m_AssetPool.Unspawn(asset); + m_AssetPool.ReleaseObject(asset); + } + else + { + throw new GameFrameworkException(Utility.Text.Format("Can not find asset of scene '{0}'.", sceneAssetName)); + } + + m_ResourceManager.m_ResourceHelper.UnloadScene(sceneAssetName, unloadSceneCallbacks, userData); + } + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源的实际路径。 + /// 此方法仅适用于二进制资源存储在磁盘(而非文件系统)中的情况。若二进制资源存储在文件系统中时,返回值将始终为空。 + public string GetBinaryPath(string binaryAssetName) + { + ResourceInfo resourceInfo = GetResourceInfo(binaryAssetName); + if (resourceInfo == null) + { + return null; + } + + if (!resourceInfo.Ready) + { + return null; + } + + if (!resourceInfo.IsLoadFromBinary) + { + return null; + } + + if (resourceInfo.UseFileSystem) + { + return null; + } + + return Utility.Path.GetRegularPath(Path.Combine(resourceInfo.StorageInReadOnly ? m_ResourceManager.m_ReadOnlyPath : m_ResourceManager.m_ReadWritePath, resourceInfo.ResourceName.FullName)); + } + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源是否存储在只读区中。 + /// 二进制资源是否存储在文件系统中。 + /// 二进制资源或存储二进制资源的文件系统,相对于只读区或者读写区的相对路径。 + /// 若二进制资源存储在文件系统中,则指示二进制资源在文件系统中的名称,否则此参数返回空。 + /// 是否获取二进制资源的实际路径成功。 + public bool GetBinaryPath(string binaryAssetName, out bool storageInReadOnly, out bool storageInFileSystem, out string relativePath, out string fileName) + { + storageInReadOnly = false; + storageInFileSystem = false; + relativePath = null; + fileName = null; + + ResourceInfo resourceInfo = GetResourceInfo(binaryAssetName); + if (resourceInfo == null) + { + return false; + } + + if (!resourceInfo.Ready) + { + return false; + } + + if (!resourceInfo.IsLoadFromBinary) + { + return false; + } + + storageInReadOnly = resourceInfo.StorageInReadOnly; + if (resourceInfo.UseFileSystem) + { + storageInFileSystem = true; + relativePath = Utility.Text.Format("{0}.{1}", resourceInfo.FileSystemName, DefaultExtension); + fileName = resourceInfo.ResourceName.FullName; + } + else + { + relativePath = resourceInfo.ResourceName.FullName; + } + + return true; + } + + /// + /// 获取二进制资源的长度。 + /// + /// 要获取长度的二进制资源的名称。 + /// 二进制资源的长度。 + public int GetBinaryLength(string binaryAssetName) + { + ResourceInfo resourceInfo = GetResourceInfo(binaryAssetName); + if (resourceInfo == null) + { + return -1; + } + + if (!resourceInfo.Ready) + { + return -1; + } + + if (!resourceInfo.IsLoadFromBinary) + { + return -1; + } + + return resourceInfo.Length; + } + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + /// 用户自定义数据。 + public void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks, object userData) + { + ResourceInfo resourceInfo = GetResourceInfo(binaryAssetName); + if (resourceInfo == null) + { + string errorMessage = Utility.Text.Format("Can not load binary '{0}' which is not exist.", binaryAssetName); + if (loadBinaryCallbacks.LoadBinaryFailureCallback != null) + { + loadBinaryCallbacks.LoadBinaryFailureCallback(binaryAssetName, LoadResourceStatus.NotExist, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + if (!resourceInfo.Ready) + { + string errorMessage = Utility.Text.Format("Can not load binary '{0}' which is not ready.", binaryAssetName); + if (loadBinaryCallbacks.LoadBinaryFailureCallback != null) + { + loadBinaryCallbacks.LoadBinaryFailureCallback(binaryAssetName, LoadResourceStatus.NotReady, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + if (!resourceInfo.IsLoadFromBinary) + { + string errorMessage = Utility.Text.Format("Can not load binary '{0}' which is not a binary asset.", binaryAssetName); + if (loadBinaryCallbacks.LoadBinaryFailureCallback != null) + { + loadBinaryCallbacks.LoadBinaryFailureCallback(binaryAssetName, LoadResourceStatus.TypeError, errorMessage, userData); + return; + } + + throw new GameFrameworkException(errorMessage); + } + + if (resourceInfo.UseFileSystem) + { + loadBinaryCallbacks.LoadBinarySuccessCallback(binaryAssetName, LoadBinaryFromFileSystem(binaryAssetName), 0f, userData); + } + else + { + string path = Utility.Path.GetRemotePath(Path.Combine(resourceInfo.StorageInReadOnly ? m_ResourceManager.m_ReadOnlyPath : m_ResourceManager.m_ReadWritePath, resourceInfo.ResourceName.FullName)); + m_ResourceManager.m_ResourceHelper.LoadBytes(path, m_LoadBytesCallbacks, LoadBinaryInfo.Create(binaryAssetName, resourceInfo, loadBinaryCallbacks, userData)); + } + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + public byte[] LoadBinaryFromFileSystem(string binaryAssetName) + { + ResourceInfo resourceInfo = GetResourceInfo(binaryAssetName); + if (resourceInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not exist.", binaryAssetName)); + } + + if (!resourceInfo.Ready) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not ready.", binaryAssetName)); + } + + if (!resourceInfo.IsLoadFromBinary) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not a binary asset.", binaryAssetName)); + } + + if (!resourceInfo.UseFileSystem) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not use file system.", binaryAssetName)); + } + + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(resourceInfo.FileSystemName, resourceInfo.StorageInReadOnly); + byte[] bytes = fileSystem.ReadFile(resourceInfo.ResourceName.FullName); + if (bytes == null) + { + return null; + } + + if (resourceInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || resourceInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + DecryptResourceCallback decryptResourceCallback = m_ResourceManager.m_DecryptResourceCallback ?? DefaultDecryptResourceCallback; + decryptResourceCallback(bytes, 0, bytes.Length, resourceInfo.ResourceName.Name, resourceInfo.ResourceName.Variant, resourceInfo.ResourceName.Extension, resourceInfo.StorageInReadOnly, resourceInfo.FileSystemName, (byte)resourceInfo.LoadType, resourceInfo.Length, resourceInfo.HashCode); + } + + return bytes; + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 存储加载二进制资源的二进制流的长度。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length) + { + ResourceInfo resourceInfo = GetResourceInfo(binaryAssetName); + if (resourceInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not exist.", binaryAssetName)); + } + + if (!resourceInfo.Ready) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not ready.", binaryAssetName)); + } + + if (!resourceInfo.IsLoadFromBinary) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not a binary asset.", binaryAssetName)); + } + + if (!resourceInfo.UseFileSystem) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not use file system.", binaryAssetName)); + } + + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(resourceInfo.FileSystemName, resourceInfo.StorageInReadOnly); + int bytesRead = fileSystem.ReadFile(resourceInfo.ResourceName.FullName, buffer, startIndex, length); + if (resourceInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || resourceInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + DecryptResourceCallback decryptResourceCallback = m_ResourceManager.m_DecryptResourceCallback ?? DefaultDecryptResourceCallback; + decryptResourceCallback(buffer, startIndex, bytesRead, resourceInfo.ResourceName.Name, resourceInfo.ResourceName.Variant, resourceInfo.ResourceName.Extension, resourceInfo.StorageInReadOnly, resourceInfo.FileSystemName, (byte)resourceInfo.LoadType, resourceInfo.Length, resourceInfo.HashCode); + } + + return bytesRead; + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + public byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, int length) + { + ResourceInfo resourceInfo = GetResourceInfo(binaryAssetName); + if (resourceInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not exist.", binaryAssetName)); + } + + if (!resourceInfo.Ready) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not ready.", binaryAssetName)); + } + + if (!resourceInfo.IsLoadFromBinary) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not a binary asset.", binaryAssetName)); + } + + if (!resourceInfo.UseFileSystem) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not use file system.", binaryAssetName)); + } + + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(resourceInfo.FileSystemName, resourceInfo.StorageInReadOnly); + byte[] bytes = fileSystem.ReadFileSegment(resourceInfo.ResourceName.FullName, offset, length); + if (bytes == null) + { + return null; + } + + if (resourceInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || resourceInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + DecryptResourceCallback decryptResourceCallback = m_ResourceManager.m_DecryptResourceCallback ?? DefaultDecryptResourceCallback; + decryptResourceCallback(bytes, 0, bytes.Length, resourceInfo.ResourceName.Name, resourceInfo.ResourceName.Variant, resourceInfo.ResourceName.Extension, resourceInfo.StorageInReadOnly, resourceInfo.FileSystemName, (byte)resourceInfo.LoadType, resourceInfo.Length, resourceInfo.HashCode); + } + + return bytes; + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int startIndex, int length) + { + ResourceInfo resourceInfo = GetResourceInfo(binaryAssetName); + if (resourceInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not exist.", binaryAssetName)); + } + + if (!resourceInfo.Ready) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not ready.", binaryAssetName)); + } + + if (!resourceInfo.IsLoadFromBinary) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not a binary asset.", binaryAssetName)); + } + + if (!resourceInfo.UseFileSystem) + { + throw new GameFrameworkException(Utility.Text.Format("Can not load binary '{0}' from file system which is not use file system.", binaryAssetName)); + } + + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(resourceInfo.FileSystemName, resourceInfo.StorageInReadOnly); + int bytesRead = fileSystem.ReadFileSegment(resourceInfo.ResourceName.FullName, offset, buffer, startIndex, length); + if (resourceInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || resourceInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + DecryptResourceCallback decryptResourceCallback = m_ResourceManager.m_DecryptResourceCallback ?? DefaultDecryptResourceCallback; + decryptResourceCallback(buffer, startIndex, bytesRead, resourceInfo.ResourceName.Name, resourceInfo.ResourceName.Variant, resourceInfo.ResourceName.Extension, resourceInfo.StorageInReadOnly, resourceInfo.FileSystemName, (byte)resourceInfo.LoadType, resourceInfo.Length, resourceInfo.HashCode); + } + + return bytesRead; + } + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + public TaskInfo[] GetAllLoadAssetInfos() + { + return m_TaskPool.GetAllTaskInfos(); + } + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + public void GetAllLoadAssetInfos(List results) + { + m_TaskPool.GetAllTaskInfos(results); + } + + private bool LoadDependencyAsset(string assetName, int priority, LoadResourceTaskBase mainTask, object userData) + { + if (mainTask == null) + { + throw new GameFrameworkException("Main task is invalid."); + } + + ResourceInfo resourceInfo = null; + string[] dependencyAssetNames = null; + if (!CheckAsset(assetName, out resourceInfo, out dependencyAssetNames)) + { + return false; + } + + if (resourceInfo.IsLoadFromBinary) + { + return false; + } + + LoadDependencyAssetTask dependencyTask = LoadDependencyAssetTask.Create(assetName, priority, resourceInfo, dependencyAssetNames, mainTask, userData); + foreach (string dependencyAssetName in dependencyAssetNames) + { + if (!LoadDependencyAsset(dependencyAssetName, priority, dependencyTask, userData)) + { + return false; + } + } + + m_TaskPool.AddTask(dependencyTask); + if (!resourceInfo.Ready) + { + m_ResourceManager.UpdateResource(resourceInfo.ResourceName); + } + + return true; + } + + private ResourceInfo GetResourceInfo(string assetName) + { + if (string.IsNullOrEmpty(assetName)) + { + return null; + } + + AssetInfo assetInfo = m_ResourceManager.GetAssetInfo(assetName); + if (assetInfo == null) + { + return null; + } + + return m_ResourceManager.GetResourceInfo(assetInfo.ResourceName); + } + + private bool CheckAsset(string assetName, out ResourceInfo resourceInfo, out string[] dependencyAssetNames) + { + resourceInfo = null; + dependencyAssetNames = null; + + if (string.IsNullOrEmpty(assetName)) + { + return false; + } + + AssetInfo assetInfo = m_ResourceManager.GetAssetInfo(assetName); + if (assetInfo == null) + { + return false; + } + + resourceInfo = m_ResourceManager.GetResourceInfo(assetInfo.ResourceName); + if (resourceInfo == null) + { + return false; + } + + dependencyAssetNames = assetInfo.GetDependencyAssetNames(); + return m_ResourceManager.m_ResourceMode == ResourceMode.UpdatableWhilePlaying ? true : resourceInfo.Ready; + } + + private void DefaultDecryptResourceCallback(byte[] bytes, int startIndex, int count, string name, string variant, string extension, bool storageInReadOnly, string fileSystem, byte loadType, int length, int hashCode) + { + Utility.Converter.GetBytes(hashCode, m_CachedHashBytes); + switch ((LoadType)loadType) + { + case LoadType.LoadFromMemoryAndQuickDecrypt: + case LoadType.LoadFromBinaryAndQuickDecrypt: + Utility.Encryption.GetQuickSelfXorBytes(bytes, m_CachedHashBytes); + break; + + case LoadType.LoadFromMemoryAndDecrypt: + case LoadType.LoadFromBinaryAndDecrypt: + Utility.Encryption.GetSelfXorBytes(bytes, m_CachedHashBytes); + break; + + default: + throw new GameFrameworkException("Not supported load type when decrypt resource."); + } + + Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength); + } + + private void OnLoadBinarySuccess(string fileUri, byte[] bytes, float duration, object userData) + { + LoadBinaryInfo loadBinaryInfo = (LoadBinaryInfo)userData; + if (loadBinaryInfo == null) + { + throw new GameFrameworkException("Load binary info is invalid."); + } + + ResourceInfo resourceInfo = loadBinaryInfo.ResourceInfo; + if (resourceInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || resourceInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + DecryptResourceCallback decryptResourceCallback = m_ResourceManager.m_DecryptResourceCallback ?? DefaultDecryptResourceCallback; + decryptResourceCallback(bytes, 0, bytes.Length, resourceInfo.ResourceName.Name, resourceInfo.ResourceName.Variant, resourceInfo.ResourceName.Extension, resourceInfo.StorageInReadOnly, resourceInfo.FileSystemName, (byte)resourceInfo.LoadType, resourceInfo.Length, resourceInfo.HashCode); + } + + loadBinaryInfo.LoadBinaryCallbacks.LoadBinarySuccessCallback(loadBinaryInfo.BinaryAssetName, bytes, duration, loadBinaryInfo.UserData); + ReferencePool.Release(loadBinaryInfo); + } + + private void OnLoadBinaryFailure(string fileUri, string errorMessage, object userData) + { + LoadBinaryInfo loadBinaryInfo = (LoadBinaryInfo)userData; + if (loadBinaryInfo == null) + { + throw new GameFrameworkException("Load binary info is invalid."); + } + + if (loadBinaryInfo.LoadBinaryCallbacks.LoadBinaryFailureCallback != null) + { + loadBinaryInfo.LoadBinaryCallbacks.LoadBinaryFailureCallback(loadBinaryInfo.BinaryAssetName, LoadResourceStatus.AssetError, errorMessage, loadBinaryInfo.UserData); + } + + ReferencePool.Release(loadBinaryInfo); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.cs.meta new file mode 100644 index 0000000..4784739 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 514dc011c4ef43c4b9e6ede6767dd547 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceName.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceName.cs new file mode 100644 index 0000000..2a077e6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceName.cs @@ -0,0 +1,168 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源名称。 + /// + [StructLayout(LayoutKind.Auto)] + private struct ResourceName : IComparable, IComparable, IEquatable + { + private static readonly Dictionary s_ResourceFullNames = new Dictionary(); + + private readonly string m_Name; + private readonly string m_Variant; + private readonly string m_Extension; + + /// + /// 初始化资源名称的新实例。 + /// + /// 资源名称。 + /// 变体名称。 + /// 扩展名称。 + public ResourceName(string name, string variant, string extension) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Resource name is invalid."); + } + + if (string.IsNullOrEmpty(extension)) + { + throw new GameFrameworkException("Resource extension is invalid."); + } + + m_Name = name; + m_Variant = variant; + m_Extension = extension; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取变体名称。 + /// + public string Variant + { + get + { + return m_Variant; + } + } + + /// + /// 获取扩展名称。 + /// + public string Extension + { + get + { + return m_Extension; + } + } + + public string FullName + { + get + { + string fullName = null; + if (s_ResourceFullNames.TryGetValue(this, out fullName)) + { + return fullName; + } + + fullName = m_Variant != null ? Utility.Text.Format("{0}.{1}.{2}", m_Name, m_Variant, m_Extension) : Utility.Text.Format("{0}.{1}", m_Name, m_Extension); + s_ResourceFullNames.Add(this, fullName); + return fullName; + } + } + + public override string ToString() + { + return FullName; + } + + public override int GetHashCode() + { + if (m_Variant == null) + { + return m_Name.GetHashCode() ^ m_Extension.GetHashCode(); + } + + return m_Name.GetHashCode() ^ m_Variant.GetHashCode() ^ m_Extension.GetHashCode(); + } + + public override bool Equals(object obj) + { + return (obj is ResourceName) && Equals((ResourceName)obj); + } + + public bool Equals(ResourceName value) + { + return string.Equals(m_Name, value.m_Name, StringComparison.Ordinal) && string.Equals(m_Variant, value.m_Variant, StringComparison.Ordinal) && string.Equals(m_Extension, value.m_Extension, StringComparison.Ordinal); + } + + public static bool operator ==(ResourceName a, ResourceName b) + { + return a.Equals(b); + } + + public static bool operator !=(ResourceName a, ResourceName b) + { + return !(a == b); + } + + public int CompareTo(object value) + { + if (value == null) + { + return 1; + } + + if (!(value is ResourceName)) + { + throw new GameFrameworkException("Type of value is invalid."); + } + + return CompareTo((ResourceName)value); + } + + public int CompareTo(ResourceName resourceName) + { + int result = string.CompareOrdinal(m_Name, resourceName.m_Name); + if (result != 0) + { + return result; + } + + result = string.CompareOrdinal(m_Variant, resourceName.m_Variant); + if (result != 0) + { + return result; + } + + return string.CompareOrdinal(m_Extension, resourceName.m_Extension); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceName.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceName.cs.meta new file mode 100644 index 0000000..2b00822 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceName.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5dce30cbf11c485499f6bbc77d9cbd10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceNameComparer.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceNameComparer.cs new file mode 100644 index 0000000..ece5d44 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceNameComparer.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源名称比较器。 + /// + private sealed class ResourceNameComparer : IComparer, IEqualityComparer + { + public int Compare(ResourceName x, ResourceName y) + { + return x.CompareTo(y); + } + + public bool Equals(ResourceName x, ResourceName y) + { + return x.Equals(y); + } + + public int GetHashCode(ResourceName obj) + { + return obj.GetHashCode(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceNameComparer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceNameComparer.cs.meta new file mode 100644 index 0000000..9d83dc5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceNameComparer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 615316025632e374da88b00240172945 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.ApplyInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.ApplyInfo.cs new file mode 100644 index 0000000..6272caf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.ApplyInfo.cs @@ -0,0 +1,169 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceUpdater + { + /// + /// 资源应用信息。 + /// + [StructLayout(LayoutKind.Auto)] + private struct ApplyInfo + { + private readonly ResourceName m_ResourceName; + private readonly string m_FileSystemName; + private readonly LoadType m_LoadType; + private readonly long m_Offset; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly int m_CompressedLength; + private readonly int m_CompressedHashCode; + private readonly string m_ResourcePath; + + /// + /// 初始化资源应用信息的新实例。 + /// + /// 资源名称。 + /// 资源所在的文件系统名称。 + /// 资源加载方式。 + /// 资源偏移。 + /// 资源大小。 + /// 资源哈希值。 + /// 压缩后大小。 + /// 压缩后哈希值。 + /// 资源路径。 + public ApplyInfo(ResourceName resourceName, string fileSystemName, LoadType loadType, long offset, int length, int hashCode, int compressedLength, int compressedHashCode, string resourcePath) + { + m_ResourceName = resourceName; + m_FileSystemName = fileSystemName; + m_LoadType = loadType; + m_Offset = offset; + m_Length = length; + m_HashCode = hashCode; + m_CompressedLength = compressedLength; + m_CompressedHashCode = compressedHashCode; + m_ResourcePath = resourcePath; + } + + /// + /// 获取资源名称。 + /// + public ResourceName ResourceName + { + get + { + return m_ResourceName; + } + } + + /// + /// 获取资源是否使用文件系统。 + /// + public bool UseFileSystem + { + get + { + return !string.IsNullOrEmpty(m_FileSystemName); + } + } + + /// + /// 获取资源所在的文件系统名称。 + /// + public string FileSystemName + { + get + { + return m_FileSystemName; + } + } + + /// + /// 获取资源加载方式。 + /// + public LoadType LoadType + { + get + { + return m_LoadType; + } + } + + /// + /// 获取资源偏移。 + /// + public long Offset + { + get + { + return m_Offset; + } + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get + { + return m_Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_HashCode; + } + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get + { + return m_CompressedLength; + } + } + + /// + /// 获取压缩后哈希值。 + /// + public int CompressedHashCode + { + get + { + return m_CompressedHashCode; + } + } + + /// + /// 获取资源路径。 + /// + public string ResourcePath + { + get + { + return m_ResourcePath; + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.ApplyInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.ApplyInfo.cs.meta new file mode 100644 index 0000000..5145119 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.ApplyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df3407b030c390c47ac9ca916dcb3571 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.UpdateInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.UpdateInfo.cs new file mode 100644 index 0000000..bd4c138 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.UpdateInfo.cs @@ -0,0 +1,186 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceUpdater + { + /// + /// 资源更新信息。 + /// + private sealed class UpdateInfo + { + private readonly ResourceName m_ResourceName; + private readonly string m_FileSystemName; + private readonly LoadType m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly int m_CompressedLength; + private readonly int m_CompressedHashCode; + private readonly string m_ResourcePath; + private bool m_Downloading; + private int m_RetryCount; + + /// + /// 初始化资源更新信息的新实例。 + /// + /// 资源名称。 + /// 资源所在的文件系统名称。 + /// 资源加载方式。 + /// 资源大小。 + /// 资源哈希值。 + /// 压缩后大小。 + /// 压缩后哈希值。 + /// 资源路径。 + public UpdateInfo(ResourceName resourceName, string fileSystemName, LoadType loadType, int length, int hashCode, int compressedLength, int compressedHashCode, string resourcePath) + { + m_ResourceName = resourceName; + m_FileSystemName = fileSystemName; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + m_CompressedLength = compressedLength; + m_CompressedHashCode = compressedHashCode; + m_ResourcePath = resourcePath; + m_Downloading = false; + m_RetryCount = 0; + } + + /// + /// 获取资源名称。 + /// + public ResourceName ResourceName + { + get + { + return m_ResourceName; + } + } + + /// + /// 获取资源是否使用文件系统。 + /// + public bool UseFileSystem + { + get + { + return !string.IsNullOrEmpty(m_FileSystemName); + } + } + + /// + /// 获取资源所在的文件系统名称。 + /// + public string FileSystemName + { + get + { + return m_FileSystemName; + } + } + + /// + /// 获取资源加载方式。 + /// + public LoadType LoadType + { + get + { + return m_LoadType; + } + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get + { + return m_Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_HashCode; + } + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get + { + return m_CompressedLength; + } + } + + /// + /// 获取压缩后哈希值。 + /// + public int CompressedHashCode + { + get + { + return m_CompressedHashCode; + } + } + + /// + /// 获取资源路径。 + /// + public string ResourcePath + { + get + { + return m_ResourcePath; + } + } + + /// + /// 获取或设置下载状态。 + /// + public bool Downloading + { + get + { + return m_Downloading; + } + set + { + m_Downloading = value; + } + } + + /// + /// 获取或设置已重试次数。 + /// + public int RetryCount + { + get + { + return m_RetryCount; + } + set + { + m_RetryCount = value; + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.UpdateInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.UpdateInfo.cs.meta new file mode 100644 index 0000000..cb90c2e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.UpdateInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a4d84f0355c75f41931227e4359c8fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.cs new file mode 100644 index 0000000..b81aef0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.cs @@ -0,0 +1,1016 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Download; +using GameFramework.FileSystem; +using System; +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源更新器。 + /// + private sealed partial class ResourceUpdater + { + private const int CachedHashBytesLength = 4; + private const int CachedBytesLength = 0x1000; + + private readonly ResourceManager m_ResourceManager; + private readonly Queue m_ApplyWaitingInfo; + private readonly List m_UpdateWaitingInfo; + private readonly HashSet m_UpdateWaitingInfoWhilePlaying; + private readonly Dictionary m_UpdateCandidateInfo; + private readonly SortedDictionary> m_CachedFileSystemsForGenerateReadWriteVersionList; + private readonly List m_CachedResourceNames; + private readonly byte[] m_CachedHashBytes; + private readonly byte[] m_CachedBytes; + private IDownloadManager m_DownloadManager; + private bool m_CheckResourcesComplete; + private string m_ApplyingResourcePackPath; + private FileStream m_ApplyingResourcePackStream; + private ResourceGroup m_UpdatingResourceGroup; + private int m_GenerateReadWriteVersionListLength; + private int m_CurrentGenerateReadWriteVersionListLength; + private int m_UpdateRetryCount; + private bool m_FailureFlag; + private string m_ReadWriteVersionListFileName; + private string m_ReadWriteVersionListTempFileName; + + public GameFrameworkAction ResourceApplyStart; + public GameFrameworkAction ResourceApplySuccess; + public GameFrameworkAction ResourceApplyFailure; + public GameFrameworkAction ResourceApplyComplete; + public GameFrameworkAction ResourceUpdateStart; + public GameFrameworkAction ResourceUpdateChanged; + public GameFrameworkAction ResourceUpdateSuccess; + public GameFrameworkAction ResourceUpdateFailure; + public GameFrameworkAction ResourceUpdateComplete; + public GameFrameworkAction ResourceUpdateAllComplete; + + /// + /// 初始化资源更新器的新实例。 + /// + /// 资源管理器。 + public ResourceUpdater(ResourceManager resourceManager) + { + m_ResourceManager = resourceManager; + m_ApplyWaitingInfo = new Queue(); + m_UpdateWaitingInfo = new List(); + m_UpdateWaitingInfoWhilePlaying = new HashSet(); + m_UpdateCandidateInfo = new Dictionary(); + m_CachedFileSystemsForGenerateReadWriteVersionList = new SortedDictionary>(StringComparer.Ordinal); + m_CachedResourceNames = new List(); + m_CachedHashBytes = new byte[CachedHashBytesLength]; + m_CachedBytes = new byte[CachedBytesLength]; + m_DownloadManager = null; + m_CheckResourcesComplete = false; + m_ApplyingResourcePackPath = null; + m_ApplyingResourcePackStream = null; + m_UpdatingResourceGroup = null; + m_GenerateReadWriteVersionListLength = 0; + m_CurrentGenerateReadWriteVersionListLength = 0; + m_UpdateRetryCount = 3; + m_FailureFlag = false; + m_ReadWriteVersionListFileName = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.m_ReadWritePath, LocalVersionListFileName)); + m_ReadWriteVersionListTempFileName = Utility.Text.Format("{0}.{1}", m_ReadWriteVersionListFileName, TempExtension); + + ResourceApplyStart = null; + ResourceApplySuccess = null; + ResourceApplyFailure = null; + ResourceApplyComplete = null; + ResourceUpdateStart = null; + ResourceUpdateChanged = null; + ResourceUpdateSuccess = null; + ResourceUpdateFailure = null; + ResourceUpdateComplete = null; + ResourceUpdateAllComplete = null; + } + + /// + /// 获取或设置每更新多少字节的资源,重新生成一次版本资源列表。 + /// + public int GenerateReadWriteVersionListLength + { + get + { + return m_GenerateReadWriteVersionListLength; + } + set + { + m_GenerateReadWriteVersionListLength = value; + } + } + + /// + /// 获取正在应用的资源包路径。 + /// + public string ApplyingResourcePackPath + { + get + { + return m_ApplyingResourcePackPath; + } + } + + /// + /// 获取等待应用资源数量。 + /// + public int ApplyWaitingCount + { + get + { + return m_ApplyWaitingInfo.Count; + } + } + + /// + /// 获取或设置资源更新重试次数。 + /// + public int UpdateRetryCount + { + get + { + return m_UpdateRetryCount; + } + set + { + m_UpdateRetryCount = value; + } + } + + /// + /// 获取正在更新的资源组。 + /// + public IResourceGroup UpdatingResourceGroup + { + get + { + return m_UpdatingResourceGroup; + } + } + + /// + /// 获取等待更新资源数量。 + /// + public int UpdateWaitingCount + { + get + { + return m_UpdateWaitingInfo.Count; + } + } + + /// + /// 获取使用时下载的等待更新资源数量。 + /// + public int UpdateWaitingWhilePlayingCount + { + get + { + return m_UpdateWaitingInfoWhilePlaying.Count; + } + } + + /// + /// 获取候选更新资源数量。 + /// + public int UpdateCandidateCount + { + get + { + return m_UpdateCandidateInfo.Count; + } + } + + /// + /// 资源更新器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_ApplyingResourcePackStream != null) + { + while (m_ApplyWaitingInfo.Count > 0) + { + ApplyInfo applyInfo = m_ApplyWaitingInfo.Dequeue(); + if (ApplyResource(applyInfo)) + { + return; + } + } + + Array.Clear(m_CachedBytes, 0, CachedBytesLength); + string resourcePackPath = m_ApplyingResourcePackPath; + m_ApplyingResourcePackPath = null; + m_ApplyingResourcePackStream.Dispose(); + m_ApplyingResourcePackStream = null; + if (ResourceApplyComplete != null) + { + ResourceApplyComplete(resourcePackPath, !m_FailureFlag); + } + + if (m_UpdateCandidateInfo.Count <= 0 && ResourceUpdateAllComplete != null) + { + ResourceUpdateAllComplete(); + } + + return; + } + + if (m_UpdateWaitingInfo.Count > 0) + { + int freeCount = m_DownloadManager.FreeAgentCount - m_DownloadManager.WaitingTaskCount; + if (freeCount > 0) + { + for (int i = 0, count = 0; i < m_UpdateWaitingInfo.Count && count < freeCount; i++) + { + if (DownloadResource(m_UpdateWaitingInfo[i])) + { + count++; + } + } + } + + return; + } + } + + /// + /// 关闭并清理资源更新器。 + /// + public void Shutdown() + { + if (m_DownloadManager != null) + { + m_DownloadManager.DownloadStart -= OnDownloadStart; + m_DownloadManager.DownloadUpdate -= OnDownloadUpdate; + m_DownloadManager.DownloadSuccess -= OnDownloadSuccess; + m_DownloadManager.DownloadFailure -= OnDownloadFailure; + } + + m_UpdateWaitingInfo.Clear(); + m_UpdateCandidateInfo.Clear(); + m_CachedFileSystemsForGenerateReadWriteVersionList.Clear(); + } + + /// + /// 设置下载管理器。 + /// + /// 下载管理器。 + public void SetDownloadManager(IDownloadManager downloadManager) + { + if (downloadManager == null) + { + throw new GameFrameworkException("Download manager is invalid."); + } + + m_DownloadManager = downloadManager; + m_DownloadManager.DownloadStart += OnDownloadStart; + m_DownloadManager.DownloadUpdate += OnDownloadUpdate; + m_DownloadManager.DownloadSuccess += OnDownloadSuccess; + m_DownloadManager.DownloadFailure += OnDownloadFailure; + } + + /// + /// 增加资源更新。 + /// + /// 资源名称。 + /// 资源所在的文件系统名称。 + /// 资源加载方式。 + /// 资源大小。 + /// 资源哈希值。 + /// 压缩后大小。 + /// 压缩后哈希值。 + /// 资源路径。 + public void AddResourceUpdate(ResourceName resourceName, string fileSystemName, LoadType loadType, int length, int hashCode, int compressedLength, int compressedHashCode, string resourcePath) + { + m_UpdateCandidateInfo.Add(resourceName, new UpdateInfo(resourceName, fileSystemName, loadType, length, hashCode, compressedLength, compressedHashCode, resourcePath)); + } + + /// + /// 检查资源完成。 + /// + /// 是否需要生成读写区版本资源列表。 + public void CheckResourceComplete(bool needGenerateReadWriteVersionList) + { + m_CheckResourcesComplete = true; + if (needGenerateReadWriteVersionList) + { + GenerateReadWriteVersionList(); + } + } + + /// + /// 应用指定资源包的资源。 + /// + /// 要应用的资源包路径。 + public void ApplyResources(string resourcePackPath) + { + if (!m_CheckResourcesComplete) + { + throw new GameFrameworkException("You must check resources complete first."); + } + + if (m_ApplyingResourcePackStream != null) + { + throw new GameFrameworkException(Utility.Text.Format("There is already a resource pack '{0}' being applied.", m_ApplyingResourcePackPath)); + } + + if (m_UpdatingResourceGroup != null) + { + throw new GameFrameworkException(Utility.Text.Format("There is already a resource group '{0}' being updated.", m_UpdatingResourceGroup.Name)); + } + + if (m_UpdateWaitingInfoWhilePlaying.Count > 0) + { + throw new GameFrameworkException("There are already some resources being updated while playing."); + } + + try + { + long length = 0L; + ResourcePackVersionList versionList = default(ResourcePackVersionList); + using (FileStream fileStream = new FileStream(resourcePackPath, FileMode.Open, FileAccess.Read)) + { + length = fileStream.Length; + versionList = m_ResourceManager.m_ResourcePackVersionListSerializer.Deserialize(fileStream); + } + + if (!versionList.IsValid) + { + throw new GameFrameworkException("Deserialize resource pack version list failure."); + } + + if (versionList.Offset + versionList.Length != length) + { + throw new GameFrameworkException("Resource pack length is invalid."); + } + + m_ApplyingResourcePackPath = resourcePackPath; + m_ApplyingResourcePackStream = new FileStream(resourcePackPath, FileMode.Open, FileAccess.Read); + m_ApplyingResourcePackStream.Position = versionList.Offset; + m_FailureFlag = false; + + long totalLength = 0L; + ResourcePackVersionList.Resource[] resources = versionList.GetResources(); + foreach (ResourcePackVersionList.Resource resource in resources) + { + ResourceName resourceName = new ResourceName(resource.Name, resource.Variant, resource.Extension); + UpdateInfo updateInfo = null; + if (!m_UpdateCandidateInfo.TryGetValue(resourceName, out updateInfo)) + { + continue; + } + + if (updateInfo.LoadType == (LoadType)resource.LoadType && updateInfo.Length == resource.Length && updateInfo.HashCode == resource.HashCode) + { + totalLength += resource.Length; + m_ApplyWaitingInfo.Enqueue(new ApplyInfo(resourceName, updateInfo.FileSystemName, (LoadType)resource.LoadType, resource.Offset, resource.Length, resource.HashCode, resource.CompressedLength, resource.CompressedHashCode, updateInfo.ResourcePath)); + } + } + + if (ResourceApplyStart != null) + { + ResourceApplyStart(m_ApplyingResourcePackPath, m_ApplyWaitingInfo.Count, totalLength); + } + } + catch (Exception exception) + { + if (m_ApplyingResourcePackStream != null) + { + m_ApplyingResourcePackStream.Dispose(); + m_ApplyingResourcePackStream = null; + } + + throw new GameFrameworkException(Utility.Text.Format("Apply resources '{0}' with exception '{1}'.", resourcePackPath, exception), exception); + } + } + + /// + /// 更新指定资源组的资源。 + /// + /// 要更新的资源组。 + public void UpdateResources(ResourceGroup resourceGroup) + { + if (m_DownloadManager == null) + { + throw new GameFrameworkException("You must set download manager first."); + } + + if (!m_CheckResourcesComplete) + { + throw new GameFrameworkException("You must check resources complete first."); + } + + if (m_ApplyingResourcePackStream != null) + { + throw new GameFrameworkException(Utility.Text.Format("There is already a resource pack '{0}' being applied.", m_ApplyingResourcePackPath)); + } + + if (m_UpdatingResourceGroup != null) + { + throw new GameFrameworkException(Utility.Text.Format("There is already a resource group '{0}' being updated.", m_UpdatingResourceGroup.Name)); + } + + if (string.IsNullOrEmpty(resourceGroup.Name)) + { + foreach (KeyValuePair updateInfo in m_UpdateCandidateInfo) + { + m_UpdateWaitingInfo.Add(updateInfo.Value); + } + } + else + { + resourceGroup.InternalGetResourceNames(m_CachedResourceNames); + foreach (ResourceName resourceName in m_CachedResourceNames) + { + UpdateInfo updateInfo = null; + if (!m_UpdateCandidateInfo.TryGetValue(resourceName, out updateInfo)) + { + continue; + } + + m_UpdateWaitingInfo.Add(updateInfo); + } + + m_CachedResourceNames.Clear(); + } + + m_UpdatingResourceGroup = resourceGroup; + m_FailureFlag = false; + } + + /// + /// 停止更新资源。 + /// + public void StopUpdateResources() + { + if (m_DownloadManager == null) + { + throw new GameFrameworkException("You must set download manager first."); + } + + if (!m_CheckResourcesComplete) + { + throw new GameFrameworkException("You must check resources complete first."); + } + + if (m_ApplyingResourcePackStream != null) + { + throw new GameFrameworkException(Utility.Text.Format("There is already a resource pack '{0}' being applied.", m_ApplyingResourcePackPath)); + } + + if (m_UpdatingResourceGroup == null) + { + throw new GameFrameworkException("There is no resource group being updated."); + } + + m_UpdateWaitingInfo.Clear(); + m_UpdatingResourceGroup = null; + } + + /// + /// 更新指定资源。 + /// + /// 要更新的资源名称。 + public void UpdateResource(ResourceName resourceName) + { + if (m_DownloadManager == null) + { + throw new GameFrameworkException("You must set download manager first."); + } + + if (!m_CheckResourcesComplete) + { + throw new GameFrameworkException("You must check resources complete first."); + } + + if (m_ApplyingResourcePackStream != null) + { + throw new GameFrameworkException(Utility.Text.Format("There is already a resource pack '{0}' being applied.", m_ApplyingResourcePackPath)); + } + + UpdateInfo updateInfo = null; + if (m_UpdateCandidateInfo.TryGetValue(resourceName, out updateInfo) && m_UpdateWaitingInfoWhilePlaying.Add(updateInfo)) + { + DownloadResource(updateInfo); + } + } + + private bool ApplyResource(ApplyInfo applyInfo) + { + long position = m_ApplyingResourcePackStream.Position; + try + { + bool compressed = applyInfo.Length != applyInfo.CompressedLength || applyInfo.HashCode != applyInfo.CompressedHashCode; + + int bytesRead = 0; + int bytesLeft = applyInfo.CompressedLength; + string directory = Path.GetDirectoryName(applyInfo.ResourcePath); + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + m_ApplyingResourcePackStream.Position += applyInfo.Offset; + using (FileStream fileStream = new FileStream(applyInfo.ResourcePath, FileMode.Create, FileAccess.ReadWrite)) + { + while ((bytesRead = m_ApplyingResourcePackStream.Read(m_CachedBytes, 0, bytesLeft < CachedBytesLength ? bytesLeft : CachedBytesLength)) > 0) + { + bytesLeft -= bytesRead; + fileStream.Write(m_CachedBytes, 0, bytesRead); + } + + if (compressed) + { + fileStream.Position = 0L; + int hashCode = Utility.Verifier.GetCrc32(fileStream); + if (hashCode != applyInfo.CompressedHashCode) + { + if (ResourceApplyFailure != null) + { + string errorMessage = Utility.Text.Format("Resource compressed hash code error, need '{0}', applied '{1}'.", applyInfo.CompressedHashCode, hashCode); + ResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, errorMessage); + } + + m_FailureFlag = true; + return false; + } + + fileStream.Position = 0L; + m_ResourceManager.PrepareCachedStream(); + if (!Utility.Compression.Decompress(fileStream, m_ResourceManager.m_CachedStream)) + { + if (ResourceApplyFailure != null) + { + string errorMessage = Utility.Text.Format("Unable to decompress resource '{0}'.", applyInfo.ResourcePath); + ResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, errorMessage); + } + + m_FailureFlag = true; + return false; + } + + fileStream.Position = 0L; + fileStream.SetLength(0L); + fileStream.Write(m_ResourceManager.m_CachedStream.GetBuffer(), 0, (int)m_ResourceManager.m_CachedStream.Length); + } + else + { + int hashCode = 0; + fileStream.Position = 0L; + if (applyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || applyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt + || applyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || applyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + Utility.Converter.GetBytes(applyInfo.HashCode, m_CachedHashBytes); + if (applyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || applyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt) + { + hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, Utility.Encryption.QuickEncryptLength); + } + else if (applyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || applyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, applyInfo.Length); + } + + Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength); + } + else + { + hashCode = Utility.Verifier.GetCrc32(fileStream); + } + + if (hashCode != applyInfo.HashCode) + { + if (ResourceApplyFailure != null) + { + string errorMessage = Utility.Text.Format("Resource hash code error, need '{0}', applied '{1}'.", applyInfo.HashCode, hashCode); + ResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, errorMessage); + } + + m_FailureFlag = true; + return false; + } + } + } + + if (applyInfo.UseFileSystem) + { + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(applyInfo.FileSystemName, false); + bool retVal = fileSystem.WriteFile(applyInfo.ResourceName.FullName, applyInfo.ResourcePath); + if (File.Exists(applyInfo.ResourcePath)) + { + File.Delete(applyInfo.ResourcePath); + } + + if (!retVal) + { + if (ResourceApplyFailure != null) + { + string errorMessage = Utility.Text.Format("Unable to write resource '{0}' to file system '{1}'.", applyInfo.ResourcePath, applyInfo.FileSystemName); + ResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, errorMessage); + } + + m_FailureFlag = true; + return false; + } + } + + string downloadingResource = Utility.Text.Format("{0}.download", applyInfo.ResourcePath); + if (File.Exists(downloadingResource)) + { + File.Delete(downloadingResource); + } + + m_UpdateCandidateInfo.Remove(applyInfo.ResourceName); + m_ResourceManager.m_ResourceInfos[applyInfo.ResourceName].MarkReady(); + m_ResourceManager.m_ReadWriteResourceInfos.Add(applyInfo.ResourceName, new ReadWriteResourceInfo(applyInfo.FileSystemName, applyInfo.LoadType, applyInfo.Length, applyInfo.HashCode)); + if (ResourceApplySuccess != null) + { + ResourceApplySuccess(applyInfo.ResourceName, applyInfo.ResourcePath, m_ApplyingResourcePackPath, applyInfo.Length, applyInfo.CompressedLength); + } + + m_CurrentGenerateReadWriteVersionListLength += applyInfo.CompressedLength; + if (m_ApplyWaitingInfo.Count <= 0 || m_CurrentGenerateReadWriteVersionListLength >= m_GenerateReadWriteVersionListLength) + { + GenerateReadWriteVersionList(); + return true; + } + + return false; + } + catch (Exception exception) + { + if (ResourceApplyFailure != null) + { + ResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, exception.ToString()); + } + + m_FailureFlag = true; + return false; + } + finally + { + m_ApplyingResourcePackStream.Position = position; + } + } + + private bool DownloadResource(UpdateInfo updateInfo) + { + if (updateInfo.Downloading) + { + return false; + } + + updateInfo.Downloading = true; + string resourceFullNameWithCrc32 = updateInfo.ResourceName.Variant != null ? Utility.Text.Format("{0}.{1}.{2:x8}.{3}", updateInfo.ResourceName.Name, updateInfo.ResourceName.Variant, updateInfo.HashCode, DefaultExtension) : Utility.Text.Format("{0}.{1:x8}.{2}", updateInfo.ResourceName.Name, updateInfo.HashCode, DefaultExtension); + m_DownloadManager.AddDownload(updateInfo.ResourcePath, Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_UpdatePrefixUri, resourceFullNameWithCrc32)), updateInfo); + return true; + } + + private void GenerateReadWriteVersionList() + { + FileStream fileStream = null; + try + { + fileStream = new FileStream(m_ReadWriteVersionListTempFileName, FileMode.Create, FileAccess.Write); + LocalVersionList.Resource[] resources = m_ResourceManager.m_ReadWriteResourceInfos.Count > 0 ? new LocalVersionList.Resource[m_ResourceManager.m_ReadWriteResourceInfos.Count] : null; + if (resources != null) + { + int index = 0; + foreach (KeyValuePair i in m_ResourceManager.m_ReadWriteResourceInfos) + { + ResourceName resourceName = i.Key; + ReadWriteResourceInfo resourceInfo = i.Value; + resources[index] = new LocalVersionList.Resource(resourceName.Name, resourceName.Variant, resourceName.Extension, (byte)resourceInfo.LoadType, resourceInfo.Length, resourceInfo.HashCode); + if (resourceInfo.UseFileSystem) + { + List resourceIndexes = null; + if (!m_CachedFileSystemsForGenerateReadWriteVersionList.TryGetValue(resourceInfo.FileSystemName, out resourceIndexes)) + { + resourceIndexes = new List(); + m_CachedFileSystemsForGenerateReadWriteVersionList.Add(resourceInfo.FileSystemName, resourceIndexes); + } + + resourceIndexes.Add(index); + } + + index++; + } + } + + LocalVersionList.FileSystem[] fileSystems = m_CachedFileSystemsForGenerateReadWriteVersionList.Count > 0 ? new LocalVersionList.FileSystem[m_CachedFileSystemsForGenerateReadWriteVersionList.Count] : null; + if (fileSystems != null) + { + int index = 0; + foreach (KeyValuePair> i in m_CachedFileSystemsForGenerateReadWriteVersionList) + { + fileSystems[index++] = new LocalVersionList.FileSystem(i.Key, i.Value.ToArray()); + i.Value.Clear(); + } + } + + LocalVersionList versionList = new LocalVersionList(resources, fileSystems); + if (!m_ResourceManager.m_ReadWriteVersionListSerializer.Serialize(fileStream, versionList)) + { + throw new GameFrameworkException("Serialize read-write version list failure."); + } + + if (fileStream != null) + { + fileStream.Dispose(); + fileStream = null; + } + } + catch (Exception exception) + { + if (fileStream != null) + { + fileStream.Dispose(); + fileStream = null; + } + + if (File.Exists(m_ReadWriteVersionListTempFileName)) + { + File.Delete(m_ReadWriteVersionListTempFileName); + } + + throw new GameFrameworkException(Utility.Text.Format("Generate read-write version list exception '{0}'.", exception), exception); + } + + if (File.Exists(m_ReadWriteVersionListFileName)) + { + File.Delete(m_ReadWriteVersionListFileName); + } + + File.Move(m_ReadWriteVersionListTempFileName, m_ReadWriteVersionListFileName); + m_CurrentGenerateReadWriteVersionListLength = 0; + } + + private void OnDownloadStart(object sender, DownloadStartEventArgs e) + { + UpdateInfo updateInfo = e.UserData as UpdateInfo; + if (updateInfo == null) + { + return; + } + + if (m_DownloadManager == null) + { + throw new GameFrameworkException("You must set download manager first."); + } + + if (e.CurrentLength > int.MaxValue) + { + throw new GameFrameworkException(Utility.Text.Format("File '{0}' is too large.", e.DownloadPath)); + } + + if (ResourceUpdateStart != null) + { + ResourceUpdateStart(updateInfo.ResourceName, e.DownloadPath, e.DownloadUri, (int)e.CurrentLength, updateInfo.CompressedLength, updateInfo.RetryCount); + } + } + + private void OnDownloadUpdate(object sender, DownloadUpdateEventArgs e) + { + UpdateInfo updateInfo = e.UserData as UpdateInfo; + if (updateInfo == null) + { + return; + } + + if (m_DownloadManager == null) + { + throw new GameFrameworkException("You must set download manager first."); + } + + if (e.CurrentLength > updateInfo.CompressedLength) + { + m_DownloadManager.RemoveDownload(e.SerialId); + string downloadFile = Utility.Text.Format("{0}.download", e.DownloadPath); + if (File.Exists(downloadFile)) + { + File.Delete(downloadFile); + } + + string errorMessage = Utility.Text.Format("When download update, downloaded length is larger than compressed length, need '{0}', downloaded '{1}'.", updateInfo.CompressedLength, e.CurrentLength); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + if (ResourceUpdateChanged != null) + { + ResourceUpdateChanged(updateInfo.ResourceName, e.DownloadPath, e.DownloadUri, (int)e.CurrentLength, updateInfo.CompressedLength); + } + } + + private void OnDownloadSuccess(object sender, DownloadSuccessEventArgs e) + { + UpdateInfo updateInfo = e.UserData as UpdateInfo; + if (updateInfo == null) + { + return; + } + + try + { + using (FileStream fileStream = new FileStream(e.DownloadPath, FileMode.Open, FileAccess.ReadWrite)) + { + bool compressed = updateInfo.Length != updateInfo.CompressedLength || updateInfo.HashCode != updateInfo.CompressedHashCode; + + int length = (int)fileStream.Length; + if (length != updateInfo.CompressedLength) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Resource compressed length error, need '{0}', downloaded '{1}'.", updateInfo.CompressedLength, length); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + if (compressed) + { + fileStream.Position = 0L; + int hashCode = Utility.Verifier.GetCrc32(fileStream); + if (hashCode != updateInfo.CompressedHashCode) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Resource compressed hash code error, need '{0}', downloaded '{1}'.", updateInfo.CompressedHashCode, hashCode); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + fileStream.Position = 0L; + m_ResourceManager.PrepareCachedStream(); + if (!Utility.Compression.Decompress(fileStream, m_ResourceManager.m_CachedStream)) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Unable to decompress resource '{0}'.", e.DownloadPath); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + int uncompressedLength = (int)m_ResourceManager.m_CachedStream.Length; + if (uncompressedLength != updateInfo.Length) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Resource length error, need '{0}', downloaded '{1}'.", updateInfo.Length, uncompressedLength); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + fileStream.Position = 0L; + fileStream.SetLength(0L); + fileStream.Write(m_ResourceManager.m_CachedStream.GetBuffer(), 0, uncompressedLength); + } + else + { + int hashCode = 0; + fileStream.Position = 0L; + if (updateInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || updateInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt + || updateInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || updateInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + Utility.Converter.GetBytes(updateInfo.HashCode, m_CachedHashBytes); + if (updateInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || updateInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt) + { + hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, Utility.Encryption.QuickEncryptLength); + } + else if (updateInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || updateInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, length); + } + + Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength); + } + else + { + hashCode = Utility.Verifier.GetCrc32(fileStream); + } + + if (hashCode != updateInfo.HashCode) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Resource hash code error, need '{0}', downloaded '{1}'.", updateInfo.HashCode, hashCode); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + } + } + + if (updateInfo.UseFileSystem) + { + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(updateInfo.FileSystemName, false); + bool retVal = fileSystem.WriteFile(updateInfo.ResourceName.FullName, updateInfo.ResourcePath); + if (File.Exists(updateInfo.ResourcePath)) + { + File.Delete(updateInfo.ResourcePath); + } + + if (!retVal) + { + string errorMessage = Utility.Text.Format("Write resource to file system '{0}' error.", fileSystem.FullPath); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + } + + m_UpdateCandidateInfo.Remove(updateInfo.ResourceName); + m_UpdateWaitingInfo.Remove(updateInfo); + m_UpdateWaitingInfoWhilePlaying.Remove(updateInfo); + m_ResourceManager.m_ResourceInfos[updateInfo.ResourceName].MarkReady(); + m_ResourceManager.m_ReadWriteResourceInfos.Add(updateInfo.ResourceName, new ReadWriteResourceInfo(updateInfo.FileSystemName, updateInfo.LoadType, updateInfo.Length, updateInfo.HashCode)); + if (ResourceUpdateSuccess != null) + { + ResourceUpdateSuccess(updateInfo.ResourceName, e.DownloadPath, e.DownloadUri, updateInfo.Length, updateInfo.CompressedLength); + } + + m_CurrentGenerateReadWriteVersionListLength += updateInfo.CompressedLength; + if (m_UpdateCandidateInfo.Count <= 0 || m_UpdateWaitingInfo.Count + m_UpdateWaitingInfoWhilePlaying.Count <= 0 || m_CurrentGenerateReadWriteVersionListLength >= m_GenerateReadWriteVersionListLength) + { + GenerateReadWriteVersionList(); + } + + if (m_UpdatingResourceGroup != null && m_UpdateWaitingInfo.Count <= 0) + { + ResourceGroup updatingResourceGroup = m_UpdatingResourceGroup; + m_UpdatingResourceGroup = null; + if (ResourceUpdateComplete != null) + { + ResourceUpdateComplete(updatingResourceGroup, !m_FailureFlag); + } + } + + if (m_UpdateCandidateInfo.Count <= 0 && ResourceUpdateAllComplete != null) + { + ResourceUpdateAllComplete(); + } + } + catch (Exception exception) + { + string errorMessage = Utility.Text.Format("Update resource '{0}' with error message '{1}'.", e.DownloadPath, exception); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + } + } + + private void OnDownloadFailure(object sender, DownloadFailureEventArgs e) + { + UpdateInfo updateInfo = e.UserData as UpdateInfo; + if (updateInfo == null) + { + return; + } + + if (File.Exists(e.DownloadPath)) + { + File.Delete(e.DownloadPath); + } + + if (ResourceUpdateFailure != null) + { + ResourceUpdateFailure(updateInfo.ResourceName, e.DownloadUri, updateInfo.RetryCount, m_UpdateRetryCount, e.ErrorMessage); + } + + if (updateInfo.RetryCount < m_UpdateRetryCount) + { + updateInfo.Downloading = false; + updateInfo.RetryCount++; + if (m_UpdateWaitingInfoWhilePlaying.Contains(updateInfo)) + { + DownloadResource(updateInfo); + } + } + else + { + m_FailureFlag = true; + updateInfo.Downloading = false; + updateInfo.RetryCount = 0; + m_UpdateWaitingInfo.Remove(updateInfo); + m_UpdateWaitingInfoWhilePlaying.Remove(updateInfo); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.cs.meta new file mode 100644 index 0000000..8de46ce --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceUpdater.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55c246252956f824181c979527ccc63b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.VerifyInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.VerifyInfo.cs new file mode 100644 index 0000000..b6d2a6e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.VerifyInfo.cs @@ -0,0 +1,110 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private sealed partial class ResourceVerifier + { + /// + /// 资源校验信息。 + /// + private struct VerifyInfo + { + private readonly ResourceName m_ResourceName; + private readonly string m_FileSystemName; + private readonly LoadType m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + + /// + /// 初始化资源校验信息的新实例。 + /// + /// 资源名称。 + /// 资源所在的文件系统名称。 + /// 资源加载方式。 + /// 资源大小。 + /// 资源哈希值。 + public VerifyInfo(ResourceName resourceName, string fileSystemName, LoadType loadType, int length, int hashCode) + { + m_ResourceName = resourceName; + m_FileSystemName = fileSystemName; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + } + + /// + /// 获取资源名称。 + /// + public ResourceName ResourceName + { + get + { + return m_ResourceName; + } + } + + /// + /// 获取资源是否使用文件系统。 + /// + public bool UseFileSystem + { + get + { + return !string.IsNullOrEmpty(m_FileSystemName); + } + } + + /// + /// 获取资源所在的文件系统名称。 + /// + public string FileSystemName + { + get + { + return m_FileSystemName; + } + } + + /// + /// 获取资源加载方式。 + /// + public LoadType LoadType + { + get + { + return m_LoadType; + } + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get + { + return m_Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_HashCode; + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.VerifyInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.VerifyInfo.cs.meta new file mode 100644 index 0000000..e863eca --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.VerifyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 66af4330fb3928944a68c9a34c76a527 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.cs new file mode 100644 index 0000000..ff6aa9b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.cs @@ -0,0 +1,389 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; +using System; +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 资源校验器。 + /// + private sealed partial class ResourceVerifier + { + private const int CachedHashBytesLength = 4; + + private readonly ResourceManager m_ResourceManager; + private readonly List m_VerifyInfos; + private readonly byte[] m_CachedHashBytes; + private bool m_LoadReadWriteVersionListComplete; + private int m_VerifyResourceLengthPerFrame; + private int m_VerifyResourceIndex; + private bool m_FailureFlag; + + public GameFrameworkAction ResourceVerifyStart; + public GameFrameworkAction ResourceVerifySuccess; + public GameFrameworkAction ResourceVerifyFailure; + public GameFrameworkAction ResourceVerifyComplete; + + /// + /// 初始化资源校验器的新实例。 + /// + /// 资源管理器。 + public ResourceVerifier(ResourceManager resourceManager) + { + m_ResourceManager = resourceManager; + m_VerifyInfos = new List(); + m_CachedHashBytes = new byte[CachedHashBytesLength]; + m_LoadReadWriteVersionListComplete = false; + m_VerifyResourceLengthPerFrame = 0; + m_VerifyResourceIndex = 0; + m_FailureFlag = false; + + ResourceVerifyStart = null; + ResourceVerifySuccess = null; + ResourceVerifyFailure = null; + ResourceVerifyComplete = null; + } + + /// + /// 资源校验器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + if (!m_LoadReadWriteVersionListComplete) + { + return; + } + + int length = 0; + while (m_VerifyResourceIndex < m_VerifyInfos.Count) + { + VerifyInfo verifyInfo = m_VerifyInfos[m_VerifyResourceIndex]; + length += verifyInfo.Length; + if (VerifyResource(verifyInfo)) + { + m_VerifyResourceIndex++; + if (ResourceVerifySuccess != null) + { + ResourceVerifySuccess(verifyInfo.ResourceName, verifyInfo.Length); + } + } + else + { + m_FailureFlag = true; + m_VerifyInfos.RemoveAt(m_VerifyResourceIndex); + if (ResourceVerifyFailure != null) + { + ResourceVerifyFailure(verifyInfo.ResourceName); + } + } + + if (length >= m_VerifyResourceLengthPerFrame) + { + return; + } + } + + m_LoadReadWriteVersionListComplete = false; + if (m_FailureFlag) + { + GenerateReadWriteVersionList(); + } + + if (ResourceVerifyComplete != null) + { + ResourceVerifyComplete(!m_FailureFlag); + } + } + + /// + /// 关闭并清理资源校验器。 + /// + public void Shutdown() + { + m_VerifyInfos.Clear(); + m_LoadReadWriteVersionListComplete = false; + m_VerifyResourceLengthPerFrame = 0; + m_VerifyResourceIndex = 0; + m_FailureFlag = false; + } + + /// + /// 校验资源。 + /// + /// 每帧至少校验资源的大小,以字节为单位。 + public void VerifyResources(int verifyResourceLengthPerFrame) + { + if (verifyResourceLengthPerFrame < 0) + { + throw new GameFrameworkException("Verify resource count per frame is invalid."); + } + + if (m_ResourceManager.m_ResourceHelper == null) + { + throw new GameFrameworkException("Resource helper is invalid."); + } + + if (string.IsNullOrEmpty(m_ResourceManager.m_ReadWritePath)) + { + throw new GameFrameworkException("Read-write path is invalid."); + } + + m_VerifyResourceLengthPerFrame = verifyResourceLengthPerFrame; + m_ResourceManager.m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_ReadWritePath, LocalVersionListFileName)), new LoadBytesCallbacks(OnLoadReadWriteVersionListSuccess, OnLoadReadWriteVersionListFailure), null); + } + + private bool VerifyResource(VerifyInfo verifyInfo) + { + if (verifyInfo.UseFileSystem) + { + IFileSystem fileSystem = m_ResourceManager.GetFileSystem(verifyInfo.FileSystemName, false); + string fileName = verifyInfo.ResourceName.FullName; + FileSystem.FileInfo fileInfo = fileSystem.GetFileInfo(fileName); + if (!fileInfo.IsValid) + { + return false; + } + + int length = fileInfo.Length; + if (length == verifyInfo.Length) + { + m_ResourceManager.PrepareCachedStream(); + fileSystem.ReadFile(fileName, m_ResourceManager.m_CachedStream); + m_ResourceManager.m_CachedStream.Position = 0L; + int hashCode = 0; + if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt + || verifyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + Utility.Converter.GetBytes(verifyInfo.HashCode, m_CachedHashBytes); + if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt) + { + hashCode = Utility.Verifier.GetCrc32(m_ResourceManager.m_CachedStream, m_CachedHashBytes, Utility.Encryption.QuickEncryptLength); + } + else if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + hashCode = Utility.Verifier.GetCrc32(m_ResourceManager.m_CachedStream, m_CachedHashBytes, length); + } + + Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength); + } + else + { + hashCode = Utility.Verifier.GetCrc32(m_ResourceManager.m_CachedStream); + } + + if (hashCode == verifyInfo.HashCode) + { + return true; + } + } + + fileSystem.DeleteFile(fileName); + return false; + } + else + { + string resourcePath = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.ReadWritePath, verifyInfo.ResourceName.FullName)); + if (!File.Exists(resourcePath)) + { + return false; + } + + using (FileStream fileStream = new FileStream(resourcePath, FileMode.Open, FileAccess.Read)) + { + int length = (int)fileStream.Length; + if (length == verifyInfo.Length) + { + int hashCode = 0; + if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt + || verifyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + Utility.Converter.GetBytes(verifyInfo.HashCode, m_CachedHashBytes); + if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt) + { + hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, Utility.Encryption.QuickEncryptLength); + } + else if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) + { + hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, length); + } + + Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength); + } + else + { + hashCode = Utility.Verifier.GetCrc32(fileStream); + } + + if (hashCode == verifyInfo.HashCode) + { + return true; + } + } + } + + File.Delete(resourcePath); + return false; + } + } + + private void GenerateReadWriteVersionList() + { + string readWriteVersionListFileName = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.m_ReadWritePath, LocalVersionListFileName)); + string readWriteVersionListTempFileName = Utility.Text.Format("{0}.{1}", readWriteVersionListFileName, TempExtension); + SortedDictionary> cachedFileSystemsForGenerateReadWriteVersionList = new SortedDictionary>(StringComparer.Ordinal); + FileStream fileStream = null; + try + { + fileStream = new FileStream(readWriteVersionListTempFileName, FileMode.Create, FileAccess.Write); + LocalVersionList.Resource[] resources = m_VerifyInfos.Count > 0 ? new LocalVersionList.Resource[m_VerifyInfos.Count] : null; + if (resources != null) + { + int index = 0; + foreach (VerifyInfo i in m_VerifyInfos) + { + resources[index] = new LocalVersionList.Resource(i.ResourceName.Name, i.ResourceName.Variant, i.ResourceName.Extension, (byte)i.LoadType, i.Length, i.HashCode); + if (i.UseFileSystem) + { + List resourceIndexes = null; + if (!cachedFileSystemsForGenerateReadWriteVersionList.TryGetValue(i.FileSystemName, out resourceIndexes)) + { + resourceIndexes = new List(); + cachedFileSystemsForGenerateReadWriteVersionList.Add(i.FileSystemName, resourceIndexes); + } + + resourceIndexes.Add(index); + } + + index++; + } + } + + LocalVersionList.FileSystem[] fileSystems = cachedFileSystemsForGenerateReadWriteVersionList.Count > 0 ? new LocalVersionList.FileSystem[cachedFileSystemsForGenerateReadWriteVersionList.Count] : null; + if (fileSystems != null) + { + int index = 0; + foreach (KeyValuePair> i in cachedFileSystemsForGenerateReadWriteVersionList) + { + fileSystems[index++] = new LocalVersionList.FileSystem(i.Key, i.Value.ToArray()); + i.Value.Clear(); + } + } + + LocalVersionList versionList = new LocalVersionList(resources, fileSystems); + if (!m_ResourceManager.m_ReadWriteVersionListSerializer.Serialize(fileStream, versionList)) + { + throw new GameFrameworkException("Serialize read-write version list failure."); + } + + if (fileStream != null) + { + fileStream.Dispose(); + fileStream = null; + } + } + catch (Exception exception) + { + if (fileStream != null) + { + fileStream.Dispose(); + fileStream = null; + } + + if (File.Exists(readWriteVersionListTempFileName)) + { + File.Delete(readWriteVersionListTempFileName); + } + + throw new GameFrameworkException(Utility.Text.Format("Generate read-write version list exception '{0}'.", exception), exception); + } + + if (File.Exists(readWriteVersionListFileName)) + { + File.Delete(readWriteVersionListFileName); + } + + File.Move(readWriteVersionListTempFileName, readWriteVersionListFileName); + } + + private void OnLoadReadWriteVersionListSuccess(string fileUri, byte[] bytes, float duration, object userData) + { + MemoryStream memoryStream = null; + try + { + memoryStream = new MemoryStream(bytes, false); + LocalVersionList versionList = m_ResourceManager.m_ReadWriteVersionListSerializer.Deserialize(memoryStream); + if (!versionList.IsValid) + { + throw new GameFrameworkException("Deserialize read write version list failure."); + } + + LocalVersionList.Resource[] resources = versionList.GetResources(); + LocalVersionList.FileSystem[] fileSystems = versionList.GetFileSystems(); + Dictionary resourceInFileSystemNames = new Dictionary(); + foreach (LocalVersionList.FileSystem fileSystem in fileSystems) + { + int[] resourceIndexes = fileSystem.GetResourceIndexes(); + foreach (int resourceIndex in resourceIndexes) + { + LocalVersionList.Resource resource = resources[resourceIndex]; + resourceInFileSystemNames.Add(new ResourceName(resource.Name, resource.Variant, resource.Extension), fileSystem.Name); + } + } + + long totalLength = 0L; + foreach (LocalVersionList.Resource resource in resources) + { + ResourceName resourceName = new ResourceName(resource.Name, resource.Variant, resource.Extension); + string fileSystemName = null; + resourceInFileSystemNames.TryGetValue(resourceName, out fileSystemName); + totalLength += resource.Length; + m_VerifyInfos.Add(new VerifyInfo(resourceName, fileSystemName, (LoadType)resource.LoadType, resource.Length, resource.HashCode)); + } + + m_LoadReadWriteVersionListComplete = true; + if (ResourceVerifyStart != null) + { + ResourceVerifyStart(m_VerifyInfos.Count, totalLength); + } + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Utility.Text.Format("Parse read-write version list exception '{0}'.", exception), exception); + } + finally + { + if (memoryStream != null) + { + memoryStream.Dispose(); + memoryStream = null; + } + } + } + + private void OnLoadReadWriteVersionListFailure(string fileUri, string errorMessage, object userData) + { + if (ResourceVerifyComplete != null) + { + ResourceVerifyComplete(true); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.cs.meta new file mode 100644 index 0000000..0959144 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.ResourceVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 318384a89313df94c902e3d9e8a558d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.VersionListProcessor.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.VersionListProcessor.cs new file mode 100644 index 0000000..d5caff4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.VersionListProcessor.cs @@ -0,0 +1,249 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Download; +using System; +using System.IO; + +namespace GameFramework.Resource +{ + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + /// + /// 版本资源列表处理器。 + /// + private sealed class VersionListProcessor + { + private readonly ResourceManager m_ResourceManager; + private IDownloadManager m_DownloadManager; + private int m_VersionListLength; + private int m_VersionListHashCode; + private int m_VersionListCompressedLength; + private int m_VersionListCompressedHashCode; + + public GameFrameworkAction VersionListUpdateSuccess; + public GameFrameworkAction VersionListUpdateFailure; + + /// + /// 初始化版本资源列表处理器的新实例。 + /// + /// 资源管理器。 + public VersionListProcessor(ResourceManager resourceManager) + { + m_ResourceManager = resourceManager; + m_DownloadManager = null; + m_VersionListLength = 0; + m_VersionListHashCode = 0; + m_VersionListCompressedLength = 0; + m_VersionListCompressedHashCode = 0; + + VersionListUpdateSuccess = null; + VersionListUpdateFailure = null; + } + + /// + /// 关闭并清理版本资源列表处理器。 + /// + public void Shutdown() + { + if (m_DownloadManager != null) + { + m_DownloadManager.DownloadSuccess -= OnDownloadSuccess; + m_DownloadManager.DownloadFailure -= OnDownloadFailure; + } + } + + /// + /// 设置下载管理器。 + /// + /// 下载管理器。 + public void SetDownloadManager(IDownloadManager downloadManager) + { + if (downloadManager == null) + { + throw new GameFrameworkException("Download manager is invalid."); + } + + m_DownloadManager = downloadManager; + m_DownloadManager.DownloadSuccess += OnDownloadSuccess; + m_DownloadManager.DownloadFailure += OnDownloadFailure; + } + + /// + /// 检查版本资源列表。 + /// + /// 最新的内部资源版本号。 + /// 检查版本资源列表结果。 + public CheckVersionListResult CheckVersionList(int latestInternalResourceVersion) + { + if (string.IsNullOrEmpty(m_ResourceManager.m_ReadWritePath)) + { + throw new GameFrameworkException("Read-write path is invalid."); + } + + string versionListFileName = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.m_ReadWritePath, RemoteVersionListFileName)); + if (!File.Exists(versionListFileName)) + { + return CheckVersionListResult.NeedUpdate; + } + + int internalResourceVersion = 0; + FileStream fileStream = null; + try + { + fileStream = new FileStream(versionListFileName, FileMode.Open, FileAccess.Read); + object internalResourceVersionObject = null; + if (!m_ResourceManager.m_UpdatableVersionListSerializer.TryGetValue(fileStream, "InternalResourceVersion", out internalResourceVersionObject)) + { + return CheckVersionListResult.NeedUpdate; + } + + internalResourceVersion = (int)internalResourceVersionObject; + } + catch + { + return CheckVersionListResult.NeedUpdate; + } + finally + { + if (fileStream != null) + { + fileStream.Dispose(); + fileStream = null; + } + } + + if (internalResourceVersion != latestInternalResourceVersion) + { + return CheckVersionListResult.NeedUpdate; + } + + return CheckVersionListResult.Updated; + } + + /// + /// 更新版本资源列表。 + /// + /// 版本资源列表大小。 + /// 版本资源列表哈希值。 + /// 版本资源列表压缩后大小。 + /// 版本资源列表压缩后哈希值。 + public void UpdateVersionList(int versionListLength, int versionListHashCode, int versionListCompressedLength, int versionListCompressedHashCode) + { + if (m_DownloadManager == null) + { + throw new GameFrameworkException("You must set download manager first."); + } + + m_VersionListLength = versionListLength; + m_VersionListHashCode = versionListHashCode; + m_VersionListCompressedLength = versionListCompressedLength; + m_VersionListCompressedHashCode = versionListCompressedHashCode; + string localVersionListFilePath = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.m_ReadWritePath, RemoteVersionListFileName)); + int dotPosition = RemoteVersionListFileName.LastIndexOf('.'); + string latestVersionListFullNameWithCrc32 = Utility.Text.Format("{0}.{2:x8}.{1}", RemoteVersionListFileName.Substring(0, dotPosition), RemoteVersionListFileName.Substring(dotPosition + 1), m_VersionListHashCode); + m_DownloadManager.AddDownload(localVersionListFilePath, Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_UpdatePrefixUri, latestVersionListFullNameWithCrc32)), this); + } + + private void OnDownloadSuccess(object sender, DownloadSuccessEventArgs e) + { + VersionListProcessor versionListProcessor = e.UserData as VersionListProcessor; + if (versionListProcessor == null || versionListProcessor != this) + { + return; + } + + try + { + using (FileStream fileStream = new FileStream(e.DownloadPath, FileMode.Open, FileAccess.ReadWrite)) + { + int length = (int)fileStream.Length; + if (length != m_VersionListCompressedLength) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Latest version list compressed length error, need '{0}', downloaded '{1}'.", m_VersionListCompressedLength, length); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + fileStream.Position = 0L; + int hashCode = Utility.Verifier.GetCrc32(fileStream); + if (hashCode != m_VersionListCompressedHashCode) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Latest version list compressed hash code error, need '{0}', downloaded '{1}'.", m_VersionListCompressedHashCode, hashCode); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + fileStream.Position = 0L; + m_ResourceManager.PrepareCachedStream(); + if (!Utility.Compression.Decompress(fileStream, m_ResourceManager.m_CachedStream)) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Unable to decompress latest version list '{0}'.", e.DownloadPath); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + int uncompressedLength = (int)m_ResourceManager.m_CachedStream.Length; + if (uncompressedLength != m_VersionListLength) + { + fileStream.Close(); + string errorMessage = Utility.Text.Format("Latest version list length error, need '{0}', downloaded '{1}'.", m_VersionListLength, uncompressedLength); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + return; + } + + fileStream.Position = 0L; + fileStream.SetLength(0L); + fileStream.Write(m_ResourceManager.m_CachedStream.GetBuffer(), 0, uncompressedLength); + } + + if (VersionListUpdateSuccess != null) + { + VersionListUpdateSuccess(e.DownloadPath, e.DownloadUri); + } + } + catch (Exception exception) + { + string errorMessage = Utility.Text.Format("Update latest version list '{0}' with error message '{1}'.", e.DownloadPath, exception); + DownloadFailureEventArgs downloadFailureEventArgs = DownloadFailureEventArgs.Create(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData); + OnDownloadFailure(this, downloadFailureEventArgs); + ReferencePool.Release(downloadFailureEventArgs); + } + } + + private void OnDownloadFailure(object sender, DownloadFailureEventArgs e) + { + VersionListProcessor versionListProcessor = e.UserData as VersionListProcessor; + if (versionListProcessor == null || versionListProcessor != this) + { + return; + } + + if (File.Exists(e.DownloadPath)) + { + File.Delete(e.DownloadPath); + } + + if (VersionListUpdateFailure != null) + { + VersionListUpdateFailure(e.DownloadUri, e.ErrorMessage); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.VersionListProcessor.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.VersionListProcessor.cs.meta new file mode 100644 index 0000000..3c58369 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.VersionListProcessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e63f681247edbd4782b772c6caaf4ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.cs new file mode 100644 index 0000000..a6656bb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.cs @@ -0,0 +1,2587 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Download; +using GameFramework.FileSystem; +using GameFramework.ObjectPool; +using System; +using System.Collections.Generic; +using System.IO; + +namespace GameFramework.Resource +{ + /// + /// 资源管理器。 + /// + internal sealed partial class ResourceManager : GameFrameworkModule, IResourceManager + { + private const string RemoteVersionListFileName = "GameFrameworkVersion.dat"; + private const string LocalVersionListFileName = "GameFrameworkList.dat"; + private const string DefaultExtension = "dat"; + private const string TempExtension = "tmp"; + private const int FileSystemMaxFileCount = 1024 * 16; + private const int FileSystemMaxBlockCount = 1024 * 256; + + private Dictionary m_AssetInfos; + private Dictionary m_ResourceInfos; + private SortedDictionary m_ReadWriteResourceInfos; + private readonly Dictionary m_ReadOnlyFileSystems; + private readonly Dictionary m_ReadWriteFileSystems; + private readonly Dictionary m_ResourceGroups; + + private PackageVersionListSerializer m_PackageVersionListSerializer; + private UpdatableVersionListSerializer m_UpdatableVersionListSerializer; + private ReadOnlyVersionListSerializer m_ReadOnlyVersionListSerializer; + private ReadWriteVersionListSerializer m_ReadWriteVersionListSerializer; + private ResourcePackVersionListSerializer m_ResourcePackVersionListSerializer; + + private IFileSystemManager m_FileSystemManager; + private ResourceIniter m_ResourceIniter; + private VersionListProcessor m_VersionListProcessor; + private ResourceVerifier m_ResourceVerifier; + private ResourceChecker m_ResourceChecker; + private ResourceUpdater m_ResourceUpdater; + private ResourceLoader m_ResourceLoader; + private IResourceHelper m_ResourceHelper; + + private string m_ReadOnlyPath; + private string m_ReadWritePath; + private ResourceMode m_ResourceMode; + private bool m_RefuseSetFlag; + private string m_CurrentVariant; + private string m_UpdatePrefixUri; + private string m_ApplicableGameVersion; + private int m_InternalResourceVersion; + private MemoryStream m_CachedStream; + private DecryptResourceCallback m_DecryptResourceCallback; + private InitResourcesCompleteCallback m_InitResourcesCompleteCallback; + private UpdateVersionListCallbacks m_UpdateVersionListCallbacks; + private VerifyResourcesCompleteCallback m_VerifyResourcesCompleteCallback; + private CheckResourcesCompleteCallback m_CheckResourcesCompleteCallback; + private ApplyResourcesCompleteCallback m_ApplyResourcesCompleteCallback; + private UpdateResourcesCompleteCallback m_UpdateResourcesCompleteCallback; + private EventHandler m_ResourceVerifyStartEventHandler; + private EventHandler m_ResourceVerifySuccessEventHandler; + private EventHandler m_ResourceVerifyFailureEventHandler; + private EventHandler m_ResourceApplyStartEventHandler; + private EventHandler m_ResourceApplySuccessEventHandler; + private EventHandler m_ResourceApplyFailureEventHandler; + private EventHandler m_ResourceUpdateStartEventHandler; + private EventHandler m_ResourceUpdateChangedEventHandler; + private EventHandler m_ResourceUpdateSuccessEventHandler; + private EventHandler m_ResourceUpdateFailureEventHandler; + private EventHandler m_ResourceUpdateAllCompleteEventHandler; + + /// + /// 初始化资源管理器的新实例。 + /// + public ResourceManager() + { + m_AssetInfos = null; + m_ResourceInfos = null; + m_ReadWriteResourceInfos = null; + m_ReadOnlyFileSystems = new Dictionary(StringComparer.Ordinal); + m_ReadWriteFileSystems = new Dictionary(StringComparer.Ordinal); + m_ResourceGroups = new Dictionary(StringComparer.Ordinal); + + m_PackageVersionListSerializer = null; + m_UpdatableVersionListSerializer = null; + m_ReadOnlyVersionListSerializer = null; + m_ReadWriteVersionListSerializer = null; + m_ResourcePackVersionListSerializer = null; + + m_ResourceIniter = null; + m_VersionListProcessor = null; + m_ResourceVerifier = null; + m_ResourceChecker = null; + m_ResourceUpdater = null; + m_ResourceLoader = new ResourceLoader(this); + + m_ResourceHelper = null; + m_ReadOnlyPath = null; + m_ReadWritePath = null; + m_ResourceMode = ResourceMode.Unspecified; + m_RefuseSetFlag = false; + m_CurrentVariant = null; + m_UpdatePrefixUri = null; + m_ApplicableGameVersion = null; + m_InternalResourceVersion = 0; + m_CachedStream = null; + m_DecryptResourceCallback = null; + m_InitResourcesCompleteCallback = null; + m_UpdateVersionListCallbacks = null; + m_VerifyResourcesCompleteCallback = null; + m_CheckResourcesCompleteCallback = null; + m_ApplyResourcesCompleteCallback = null; + m_UpdateResourcesCompleteCallback = null; + m_ResourceVerifySuccessEventHandler = null; + m_ResourceVerifyFailureEventHandler = null; + m_ResourceApplySuccessEventHandler = null; + m_ResourceApplyFailureEventHandler = null; + m_ResourceUpdateStartEventHandler = null; + m_ResourceUpdateChangedEventHandler = null; + m_ResourceUpdateSuccessEventHandler = null; + m_ResourceUpdateFailureEventHandler = null; + m_ResourceUpdateAllCompleteEventHandler = null; + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return 3; + } + } + + /// + /// 获取资源只读区路径。 + /// + public string ReadOnlyPath + { + get + { + return m_ReadOnlyPath; + } + } + + /// + /// 获取资源读写区路径。 + /// + public string ReadWritePath + { + get + { + return m_ReadWritePath; + } + } + + /// + /// 获取资源模式。 + /// + public ResourceMode ResourceMode + { + get + { + return m_ResourceMode; + } + } + + /// + /// 获取当前变体。 + /// + public string CurrentVariant + { + get + { + return m_CurrentVariant; + } + } + + /// + /// 获取单机模式版本资源列表序列化器。 + /// + public PackageVersionListSerializer PackageVersionListSerializer + { + get + { + return m_PackageVersionListSerializer; + } + } + + /// + /// 获取可更新模式版本资源列表序列化器。 + /// + public UpdatableVersionListSerializer UpdatableVersionListSerializer + { + get + { + return m_UpdatableVersionListSerializer; + } + } + + /// + /// 获取本地只读区版本资源列表序列化器。 + /// + public ReadOnlyVersionListSerializer ReadOnlyVersionListSerializer + { + get + { + return m_ReadOnlyVersionListSerializer; + } + } + + /// + /// 获取本地读写区版本资源列表序列化器。 + /// + public ReadWriteVersionListSerializer ReadWriteVersionListSerializer + { + get + { + return m_ReadWriteVersionListSerializer; + } + } + + /// + /// 获取资源包版本资源列表序列化器。 + /// + public ResourcePackVersionListSerializer ResourcePackVersionListSerializer + { + get + { + return m_ResourcePackVersionListSerializer; + } + } + + /// + /// 获取当前资源适用的游戏版本号。 + /// + public string ApplicableGameVersion + { + get + { + return m_ApplicableGameVersion; + } + } + + /// + /// 获取当前内部资源版本号。 + /// + public int InternalResourceVersion + { + get + { + return m_InternalResourceVersion; + } + } + + /// + /// 获取资源数量。 + /// + public int AssetCount + { + get + { + return m_AssetInfos != null ? m_AssetInfos.Count : 0; + } + } + + /// + /// 获取资源数量。 + /// + public int ResourceCount + { + get + { + return m_ResourceInfos != null ? m_ResourceInfos.Count : 0; + } + } + + /// + /// 获取资源组数量。 + /// + public int ResourceGroupCount + { + get + { + return m_ResourceGroups.Count; + } + } + + /// + /// 获取或设置资源更新下载地址前缀。 + /// + public string UpdatePrefixUri + { + get + { + return m_UpdatePrefixUri; + } + set + { + m_UpdatePrefixUri = value; + } + } + + /// + /// 获取或设置每更新多少字节的资源,重新生成一次版本资源列表。 + /// + public int GenerateReadWriteVersionListLength + { + get + { + return m_ResourceUpdater != null ? m_ResourceUpdater.GenerateReadWriteVersionListLength : 0; + } + set + { + if (m_ResourceUpdater == null) + { + throw new GameFrameworkException("You can not use GenerateReadWriteVersionListLength at this time."); + } + + m_ResourceUpdater.GenerateReadWriteVersionListLength = value; + } + } + + /// + /// 获取正在应用的资源包路径。 + /// + public string ApplyingResourcePackPath + { + get + { + return m_ResourceUpdater != null ? m_ResourceUpdater.ApplyingResourcePackPath : null; + } + } + + /// + /// 获取等待应用资源数量。 + /// + public int ApplyWaitingCount + { + get + { + return m_ResourceUpdater != null ? m_ResourceUpdater.ApplyWaitingCount : 0; + } + } + + /// + /// 获取或设置资源更新重试次数。 + /// + public int UpdateRetryCount + { + get + { + return m_ResourceUpdater != null ? m_ResourceUpdater.UpdateRetryCount : 0; + } + set + { + if (m_ResourceUpdater == null) + { + throw new GameFrameworkException("You can not use UpdateRetryCount at this time."); + } + + m_ResourceUpdater.UpdateRetryCount = value; + } + } + + /// + /// 获取正在更新的资源组。 + /// + public IResourceGroup UpdatingResourceGroup + { + get + { + return m_ResourceUpdater != null ? m_ResourceUpdater.UpdatingResourceGroup : null; + } + } + + /// + /// 获取等待更新资源数量。 + /// + public int UpdateWaitingCount + { + get + { + return m_ResourceUpdater != null ? m_ResourceUpdater.UpdateWaitingCount : 0; + } + } + + /// + /// 获取使用时下载的等待更新资源数量。 + /// + public int UpdateWaitingWhilePlayingCount + { + get + { + return m_ResourceUpdater != null ? m_ResourceUpdater.UpdateWaitingWhilePlayingCount : 0; + } + } + + /// + /// 获取候选更新资源数量。 + /// + public int UpdateCandidateCount + { + get + { + return m_ResourceUpdater != null ? m_ResourceUpdater.UpdateCandidateCount : 0; + } + } + + /// + /// 获取加载资源代理总数量。 + /// + public int LoadTotalAgentCount + { + get + { + return m_ResourceLoader.TotalAgentCount; + } + } + + /// + /// 获取可用加载资源代理数量。 + /// + public int LoadFreeAgentCount + { + get + { + return m_ResourceLoader.FreeAgentCount; + } + } + + /// + /// 获取工作中加载资源代理数量。 + /// + public int LoadWorkingAgentCount + { + get + { + return m_ResourceLoader.WorkingAgentCount; + } + } + + /// + /// 获取等待加载资源任务数量。 + /// + public int LoadWaitingTaskCount + { + get + { + return m_ResourceLoader.WaitingTaskCount; + } + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + public float AssetAutoReleaseInterval + { + get + { + return m_ResourceLoader.AssetAutoReleaseInterval; + } + set + { + m_ResourceLoader.AssetAutoReleaseInterval = value; + } + } + + /// + /// 获取或设置资源对象池的容量。 + /// + public int AssetCapacity + { + get + { + return m_ResourceLoader.AssetCapacity; + } + set + { + m_ResourceLoader.AssetCapacity = value; + } + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + public float AssetExpireTime + { + get + { + return m_ResourceLoader.AssetExpireTime; + } + set + { + m_ResourceLoader.AssetExpireTime = value; + } + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + public int AssetPriority + { + get + { + return m_ResourceLoader.AssetPriority; + } + set + { + m_ResourceLoader.AssetPriority = value; + } + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + public float ResourceAutoReleaseInterval + { + get + { + return m_ResourceLoader.ResourceAutoReleaseInterval; + } + set + { + m_ResourceLoader.ResourceAutoReleaseInterval = value; + } + } + + /// + /// 获取或设置资源对象池的容量。 + /// + public int ResourceCapacity + { + get + { + return m_ResourceLoader.ResourceCapacity; + } + set + { + m_ResourceLoader.ResourceCapacity = value; + } + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + public float ResourceExpireTime + { + get + { + return m_ResourceLoader.ResourceExpireTime; + } + set + { + m_ResourceLoader.ResourceExpireTime = value; + } + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + public int ResourcePriority + { + get + { + return m_ResourceLoader.ResourcePriority; + } + set + { + m_ResourceLoader.ResourcePriority = value; + } + } + + /// + /// 资源校验开始事件。 + /// + public event EventHandler ResourceVerifyStart + { + add + { + m_ResourceVerifyStartEventHandler += value; + } + remove + { + m_ResourceVerifyStartEventHandler -= value; + } + } + + /// + /// 资源校验成功事件。 + /// + public event EventHandler ResourceVerifySuccess + { + add + { + m_ResourceVerifySuccessEventHandler += value; + } + remove + { + m_ResourceVerifySuccessEventHandler -= value; + } + } + + /// + /// 资源校验失败事件。 + /// + public event EventHandler ResourceVerifyFailure + { + add + { + m_ResourceVerifyFailureEventHandler += value; + } + remove + { + m_ResourceVerifyFailureEventHandler -= value; + } + } + + /// + /// 资源应用开始事件。 + /// + public event EventHandler ResourceApplyStart + { + add + { + m_ResourceApplyStartEventHandler += value; + } + remove + { + m_ResourceApplyStartEventHandler -= value; + } + } + + /// + /// 资源应用成功事件。 + /// + public event EventHandler ResourceApplySuccess + { + add + { + m_ResourceApplySuccessEventHandler += value; + } + remove + { + m_ResourceApplySuccessEventHandler -= value; + } + } + + /// + /// 资源应用失败事件。 + /// + public event EventHandler ResourceApplyFailure + { + add + { + m_ResourceApplyFailureEventHandler += value; + } + remove + { + m_ResourceApplyFailureEventHandler -= value; + } + } + + /// + /// 资源更新开始事件。 + /// + public event EventHandler ResourceUpdateStart + { + add + { + m_ResourceUpdateStartEventHandler += value; + } + remove + { + m_ResourceUpdateStartEventHandler -= value; + } + } + + /// + /// 资源更新改变事件。 + /// + public event EventHandler ResourceUpdateChanged + { + add + { + m_ResourceUpdateChangedEventHandler += value; + } + remove + { + m_ResourceUpdateChangedEventHandler -= value; + } + } + + /// + /// 资源更新成功事件。 + /// + public event EventHandler ResourceUpdateSuccess + { + add + { + m_ResourceUpdateSuccessEventHandler += value; + } + remove + { + m_ResourceUpdateSuccessEventHandler -= value; + } + } + + /// + /// 资源更新失败事件。 + /// + public event EventHandler ResourceUpdateFailure + { + add + { + m_ResourceUpdateFailureEventHandler += value; + } + remove + { + m_ResourceUpdateFailureEventHandler -= value; + } + } + + /// + /// 资源更新全部完成事件。 + /// + public event EventHandler ResourceUpdateAllComplete + { + add + { + m_ResourceUpdateAllCompleteEventHandler += value; + } + remove + { + m_ResourceUpdateAllCompleteEventHandler -= value; + } + } + + /// + /// 资源管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_ResourceVerifier != null) + { + m_ResourceVerifier.Update(elapseSeconds, realElapseSeconds); + return; + } + + if (m_ResourceUpdater != null) + { + m_ResourceUpdater.Update(elapseSeconds, realElapseSeconds); + } + + m_ResourceLoader.Update(elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理资源管理器。 + /// + internal override void Shutdown() + { + if (m_ResourceIniter != null) + { + m_ResourceIniter.Shutdown(); + m_ResourceIniter = null; + } + + if (m_VersionListProcessor != null) + { + m_VersionListProcessor.VersionListUpdateSuccess -= OnVersionListProcessorUpdateSuccess; + m_VersionListProcessor.VersionListUpdateFailure -= OnVersionListProcessorUpdateFailure; + m_VersionListProcessor.Shutdown(); + m_VersionListProcessor = null; + } + + if (m_ResourceVerifier != null) + { + m_ResourceVerifier.ResourceVerifyStart -= OnVerifierResourceVerifyStart; + m_ResourceVerifier.ResourceVerifySuccess -= OnVerifierResourceVerifySuccess; + m_ResourceVerifier.ResourceVerifyFailure -= OnVerifierResourceVerifyFailure; + m_ResourceVerifier.ResourceVerifyComplete -= OnVerifierResourceVerifyComplete; + m_ResourceVerifier.Shutdown(); + m_ResourceVerifier = null; + } + + if (m_ResourceChecker != null) + { + m_ResourceChecker.ResourceNeedUpdate -= OnCheckerResourceNeedUpdate; + m_ResourceChecker.ResourceCheckComplete -= OnCheckerResourceCheckComplete; + m_ResourceChecker.Shutdown(); + m_ResourceChecker = null; + } + + if (m_ResourceUpdater != null) + { + m_ResourceUpdater.ResourceApplyStart -= OnUpdaterResourceApplyStart; + m_ResourceUpdater.ResourceApplySuccess -= OnUpdaterResourceApplySuccess; + m_ResourceUpdater.ResourceApplyFailure -= OnUpdaterResourceApplyFailure; + m_ResourceUpdater.ResourceApplyComplete -= OnUpdaterResourceApplyComplete; + m_ResourceUpdater.ResourceUpdateStart -= OnUpdaterResourceUpdateStart; + m_ResourceUpdater.ResourceUpdateChanged -= OnUpdaterResourceUpdateChanged; + m_ResourceUpdater.ResourceUpdateSuccess -= OnUpdaterResourceUpdateSuccess; + m_ResourceUpdater.ResourceUpdateFailure -= OnUpdaterResourceUpdateFailure; + m_ResourceUpdater.ResourceUpdateComplete -= OnUpdaterResourceUpdateComplete; + m_ResourceUpdater.ResourceUpdateAllComplete -= OnUpdaterResourceUpdateAllComplete; + m_ResourceUpdater.Shutdown(); + m_ResourceUpdater = null; + + if (m_ReadWriteResourceInfos != null) + { + m_ReadWriteResourceInfos.Clear(); + m_ReadWriteResourceInfos = null; + } + + FreeCachedStream(); + } + + if (m_ResourceLoader != null) + { + m_ResourceLoader.Shutdown(); + m_ResourceLoader = null; + } + + if (m_AssetInfos != null) + { + m_AssetInfos.Clear(); + m_AssetInfos = null; + } + + if (m_ResourceInfos != null) + { + m_ResourceInfos.Clear(); + m_ResourceInfos = null; + } + + m_ReadOnlyFileSystems.Clear(); + m_ReadWriteFileSystems.Clear(); + m_ResourceGroups.Clear(); + } + + /// + /// 设置资源只读区路径。 + /// + /// 资源只读区路径。 + public void SetReadOnlyPath(string readOnlyPath) + { + if (string.IsNullOrEmpty(readOnlyPath)) + { + throw new GameFrameworkException("Read-only path is invalid."); + } + + if (m_RefuseSetFlag) + { + throw new GameFrameworkException("You can not set read-only path at this time."); + } + + if (m_ResourceLoader.TotalAgentCount > 0) + { + throw new GameFrameworkException("You must set read-only path before add load resource agent helper."); + } + + m_ReadOnlyPath = readOnlyPath; + } + + /// + /// 设置资源读写区路径。 + /// + /// 资源读写区路径。 + public void SetReadWritePath(string readWritePath) + { + if (string.IsNullOrEmpty(readWritePath)) + { + throw new GameFrameworkException("Read-write path is invalid."); + } + + if (m_RefuseSetFlag) + { + throw new GameFrameworkException("You can not set read-write path at this time."); + } + + if (m_ResourceLoader.TotalAgentCount > 0) + { + throw new GameFrameworkException("You must set read-write path before add load resource agent helper."); + } + + m_ReadWritePath = readWritePath; + } + + /// + /// 设置资源模式。 + /// + /// 资源模式。 + public void SetResourceMode(ResourceMode resourceMode) + { + if (resourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("Resource mode is invalid."); + } + + if (m_RefuseSetFlag) + { + throw new GameFrameworkException("You can not set resource mode at this time."); + } + + if (m_ResourceMode == ResourceMode.Unspecified) + { + m_ResourceMode = resourceMode; + + if (m_ResourceMode == ResourceMode.Package) + { + m_PackageVersionListSerializer = new PackageVersionListSerializer(); + + m_ResourceIniter = new ResourceIniter(this); + m_ResourceIniter.ResourceInitComplete += OnIniterResourceInitComplete; + } + else if (m_ResourceMode == ResourceMode.Updatable || m_ResourceMode == ResourceMode.UpdatableWhilePlaying) + { + m_UpdatableVersionListSerializer = new UpdatableVersionListSerializer(); + m_ReadOnlyVersionListSerializer = new ReadOnlyVersionListSerializer(); + m_ReadWriteVersionListSerializer = new ReadWriteVersionListSerializer(); + m_ResourcePackVersionListSerializer = new ResourcePackVersionListSerializer(); + + m_VersionListProcessor = new VersionListProcessor(this); + m_VersionListProcessor.VersionListUpdateSuccess += OnVersionListProcessorUpdateSuccess; + m_VersionListProcessor.VersionListUpdateFailure += OnVersionListProcessorUpdateFailure; + + m_ResourceChecker = new ResourceChecker(this); + m_ResourceChecker.ResourceNeedUpdate += OnCheckerResourceNeedUpdate; + m_ResourceChecker.ResourceCheckComplete += OnCheckerResourceCheckComplete; + + m_ResourceUpdater = new ResourceUpdater(this); + m_ResourceUpdater.ResourceApplyStart += OnUpdaterResourceApplyStart; + m_ResourceUpdater.ResourceApplySuccess += OnUpdaterResourceApplySuccess; + m_ResourceUpdater.ResourceApplyFailure += OnUpdaterResourceApplyFailure; + m_ResourceUpdater.ResourceApplyComplete += OnUpdaterResourceApplyComplete; + m_ResourceUpdater.ResourceUpdateStart += OnUpdaterResourceUpdateStart; + m_ResourceUpdater.ResourceUpdateChanged += OnUpdaterResourceUpdateChanged; + m_ResourceUpdater.ResourceUpdateSuccess += OnUpdaterResourceUpdateSuccess; + m_ResourceUpdater.ResourceUpdateFailure += OnUpdaterResourceUpdateFailure; + m_ResourceUpdater.ResourceUpdateComplete += OnUpdaterResourceUpdateComplete; + m_ResourceUpdater.ResourceUpdateAllComplete += OnUpdaterResourceUpdateAllComplete; + } + } + else if (m_ResourceMode != resourceMode) + { + throw new GameFrameworkException("You can not change resource mode at this time."); + } + } + + /// + /// 设置当前变体。 + /// + /// 当前变体。 + public void SetCurrentVariant(string currentVariant) + { + if (m_RefuseSetFlag) + { + throw new GameFrameworkException("You can not set current variant at this time."); + } + + m_CurrentVariant = currentVariant; + } + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + public void SetObjectPoolManager(IObjectPoolManager objectPoolManager) + { + if (objectPoolManager == null) + { + throw new GameFrameworkException("Object pool manager is invalid."); + } + + m_ResourceLoader.SetObjectPoolManager(objectPoolManager); + } + + /// + /// 设置文件系统管理器。 + /// + /// 文件系统管理器。 + public void SetFileSystemManager(IFileSystemManager fileSystemManager) + { + if (fileSystemManager == null) + { + throw new GameFrameworkException("File system manager is invalid."); + } + + m_FileSystemManager = fileSystemManager; + } + + /// + /// 设置下载管理器。 + /// + /// 下载管理器。 + public void SetDownloadManager(IDownloadManager downloadManager) + { + if (downloadManager == null) + { + throw new GameFrameworkException("Download manager is invalid."); + } + + if (m_VersionListProcessor != null) + { + m_VersionListProcessor.SetDownloadManager(downloadManager); + } + + if (m_ResourceUpdater != null) + { + m_ResourceUpdater.SetDownloadManager(downloadManager); + } + } + + /// + /// 设置解密资源回调函数。 + /// + /// 要设置的解密资源回调函数。 + /// 如果不设置,将使用默认的解密资源回调函数。 + public void SetDecryptResourceCallback(DecryptResourceCallback decryptResourceCallback) + { + if (m_ResourceLoader.TotalAgentCount > 0) + { + throw new GameFrameworkException("You must set decrypt resource callback before add load resource agent helper."); + } + + m_DecryptResourceCallback = decryptResourceCallback; + } + + /// + /// 设置资源辅助器。 + /// + /// 资源辅助器。 + public void SetResourceHelper(IResourceHelper resourceHelper) + { + if (resourceHelper == null) + { + throw new GameFrameworkException("Resource helper is invalid."); + } + + if (m_ResourceLoader.TotalAgentCount > 0) + { + throw new GameFrameworkException("You must set resource helper before add load resource agent helper."); + } + + m_ResourceHelper = resourceHelper; + } + + /// + /// 增加加载资源代理辅助器。 + /// + /// 要增加的加载资源代理辅助器。 + public void AddLoadResourceAgentHelper(ILoadResourceAgentHelper loadResourceAgentHelper) + { + if (m_ResourceHelper == null) + { + throw new GameFrameworkException("Resource helper is invalid."); + } + + if (string.IsNullOrEmpty(m_ReadOnlyPath)) + { + throw new GameFrameworkException("Read-only path is invalid."); + } + + if (string.IsNullOrEmpty(m_ReadWritePath)) + { + throw new GameFrameworkException("Read-write path is invalid."); + } + + m_ResourceLoader.AddLoadResourceAgentHelper(loadResourceAgentHelper, m_ResourceHelper, m_ReadOnlyPath, m_ReadWritePath, m_DecryptResourceCallback); + } + + /// + /// 使用单机模式并初始化资源。 + /// + /// 使用单机模式并初始化资源完成时的回调函数。 + public void InitResources(InitResourcesCompleteCallback initResourcesCompleteCallback) + { + if (initResourcesCompleteCallback == null) + { + throw new GameFrameworkException("Init resources complete callback is invalid."); + } + + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Package) + { + throw new GameFrameworkException("You can not use InitResources without package resource mode."); + } + + if (m_ResourceIniter == null) + { + throw new GameFrameworkException("You can not use InitResources at this time."); + } + + m_RefuseSetFlag = true; + m_InitResourcesCompleteCallback = initResourcesCompleteCallback; + m_ResourceIniter.InitResources(m_CurrentVariant); + } + + /// + /// 使用可更新模式并检查版本资源列表。 + /// + /// 最新的内部资源版本号。 + /// 检查版本资源列表结果。 + public CheckVersionListResult CheckVersionList(int latestInternalResourceVersion) + { + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Updatable && m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + throw new GameFrameworkException("You can not use CheckVersionList without updatable resource mode."); + } + + if (m_VersionListProcessor == null) + { + throw new GameFrameworkException("You can not use CheckVersionList at this time."); + } + + return m_VersionListProcessor.CheckVersionList(latestInternalResourceVersion); + } + + /// + /// 使用可更新模式并更新版本资源列表。 + /// + /// 版本资源列表大小。 + /// 版本资源列表哈希值。 + /// 版本资源列表压缩后大小。 + /// 版本资源列表压缩后哈希值。 + /// 版本资源列表更新回调函数集。 + public void UpdateVersionList(int versionListLength, int versionListHashCode, int versionListCompressedLength, int versionListCompressedHashCode, UpdateVersionListCallbacks updateVersionListCallbacks) + { + if (updateVersionListCallbacks == null) + { + throw new GameFrameworkException("Update version list callbacks is invalid."); + } + + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Updatable && m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + throw new GameFrameworkException("You can not use UpdateVersionList without updatable resource mode."); + } + + if (m_VersionListProcessor == null) + { + throw new GameFrameworkException("You can not use UpdateVersionList at this time."); + } + + m_UpdateVersionListCallbacks = updateVersionListCallbacks; + m_VersionListProcessor.UpdateVersionList(versionListLength, versionListHashCode, versionListCompressedLength, versionListCompressedHashCode); + } + + /// + /// 使用可更新模式并校验资源。 + /// + /// 每帧至少校验资源的大小,以字节为单位。 + /// 使用可更新模式并校验资源完成时的回调函数。 + public void VerifyResources(int verifyResourceLengthPerFrame, VerifyResourcesCompleteCallback verifyResourcesCompleteCallback) + { + if (verifyResourcesCompleteCallback == null) + { + throw new GameFrameworkException("Verify resources complete callback is invalid."); + } + + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Updatable && m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + throw new GameFrameworkException("You can not use VerifyResources without updatable resource mode."); + } + + if (m_RefuseSetFlag) + { + throw new GameFrameworkException("You can not verify resources at this time."); + } + + m_ResourceVerifier = new ResourceVerifier(this); + m_ResourceVerifier.ResourceVerifyStart += OnVerifierResourceVerifyStart; + m_ResourceVerifier.ResourceVerifySuccess += OnVerifierResourceVerifySuccess; + m_ResourceVerifier.ResourceVerifyFailure += OnVerifierResourceVerifyFailure; + m_ResourceVerifier.ResourceVerifyComplete += OnVerifierResourceVerifyComplete; + m_VerifyResourcesCompleteCallback = verifyResourcesCompleteCallback; + m_ResourceVerifier.VerifyResources(verifyResourceLengthPerFrame); + } + + /// + /// 使用可更新模式并检查资源。 + /// + /// 是否忽略处理其它变体的资源,若不忽略,将会移除其它变体的资源。 + /// 使用可更新模式并检查资源完成时的回调函数。 + public void CheckResources(bool ignoreOtherVariant, CheckResourcesCompleteCallback checkResourcesCompleteCallback) + { + if (checkResourcesCompleteCallback == null) + { + throw new GameFrameworkException("Check resources complete callback is invalid."); + } + + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Updatable && m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + throw new GameFrameworkException("You can not use CheckResources without updatable resource mode."); + } + + if (m_ResourceChecker == null) + { + throw new GameFrameworkException("You can not use CheckResources at this time."); + } + + m_RefuseSetFlag = true; + m_CheckResourcesCompleteCallback = checkResourcesCompleteCallback; + m_ResourceChecker.CheckResources(m_CurrentVariant, ignoreOtherVariant); + } + + /// + /// 使用可更新模式并应用资源包资源。 + /// + /// 要应用的资源包路径。 + /// 使用可更新模式并应用资源包资源完成时的回调函数。 + public void ApplyResources(string resourcePackPath, ApplyResourcesCompleteCallback applyResourcesCompleteCallback) + { + if (string.IsNullOrEmpty(resourcePackPath)) + { + throw new GameFrameworkException("Resource pack path is invalid."); + } + + if (!File.Exists(resourcePackPath)) + { + throw new GameFrameworkException(Utility.Text.Format("Resource pack '{0}' is not exist.", resourcePackPath)); + } + + if (applyResourcesCompleteCallback == null) + { + throw new GameFrameworkException("Apply resources complete callback is invalid."); + } + + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Updatable && m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + throw new GameFrameworkException("You can not use ApplyResources without updatable resource mode."); + } + + if (m_ResourceUpdater == null) + { + throw new GameFrameworkException("You can not use ApplyResources at this time."); + } + + m_ApplyResourcesCompleteCallback = applyResourcesCompleteCallback; + m_ResourceUpdater.ApplyResources(resourcePackPath); + } + + /// + /// 使用可更新模式并更新所有资源。 + /// + /// 使用可更新模式并更新默认资源组完成时的回调函数。 + public void UpdateResources(UpdateResourcesCompleteCallback updateResourcesCompleteCallback) + { + UpdateResources(string.Empty, updateResourcesCompleteCallback); + } + + /// + /// 使用可更新模式并更新指定资源组的资源。 + /// + /// 要更新的资源组名称。 + /// 使用可更新模式并更新指定资源组完成时的回调函数。 + public void UpdateResources(string resourceGroupName, UpdateResourcesCompleteCallback updateResourcesCompleteCallback) + { + if (updateResourcesCompleteCallback == null) + { + throw new GameFrameworkException("Update resources complete callback is invalid."); + } + + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Updatable && m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + throw new GameFrameworkException("You can not use UpdateResources without updatable resource mode."); + } + + if (m_ResourceUpdater == null) + { + throw new GameFrameworkException("You can not use UpdateResources at this time."); + } + + ResourceGroup resourceGroup = (ResourceGroup)GetResourceGroup(resourceGroupName); + if (resourceGroup == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find resource group '{0}'.", resourceGroupName)); + } + + m_UpdateResourcesCompleteCallback = updateResourcesCompleteCallback; + m_ResourceUpdater.UpdateResources(resourceGroup); + } + + /// + /// 停止更新资源。 + /// + public void StopUpdateResources() + { + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Updatable && m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + throw new GameFrameworkException("You can not use StopUpdateResources without updatable resource mode."); + } + + if (m_ResourceUpdater == null) + { + throw new GameFrameworkException("You can not use StopUpdateResources at this time."); + } + + m_ResourceUpdater.StopUpdateResources(); + m_UpdateResourcesCompleteCallback = null; + } + + /// + /// 校验资源包。 + /// + /// 要校验的资源包路径。 + /// 是否校验资源包成功。 + public bool VerifyResourcePack(string resourcePackPath) + { + if (string.IsNullOrEmpty(resourcePackPath)) + { + throw new GameFrameworkException("Resource pack path is invalid."); + } + + if (!File.Exists(resourcePackPath)) + { + throw new GameFrameworkException(Utility.Text.Format("Resource pack '{0}' is not exist.", resourcePackPath)); + } + + if (m_ResourceMode == ResourceMode.Unspecified) + { + throw new GameFrameworkException("You must set resource mode first."); + } + + if (m_ResourceMode != ResourceMode.Updatable && m_ResourceMode != ResourceMode.UpdatableWhilePlaying) + { + throw new GameFrameworkException("You can not use VerifyResourcePack without updatable resource mode."); + } + + if (m_ResourcePackVersionListSerializer == null) + { + throw new GameFrameworkException("You can not use VerifyResourcePack at this time."); + } + + try + { + long length = 0L; + ResourcePackVersionList versionList = default(ResourcePackVersionList); + using (FileStream fileStream = new FileStream(resourcePackPath, FileMode.Open, FileAccess.Read)) + { + length = fileStream.Length; + versionList = m_ResourcePackVersionListSerializer.Deserialize(fileStream); + } + + if (!versionList.IsValid) + { + return false; + } + + if (versionList.Offset + versionList.Length != length) + { + return false; + } + + int hashCode = 0; + using (FileStream fileStream = new FileStream(resourcePackPath, FileMode.Open, FileAccess.Read)) + { + fileStream.Position = versionList.Offset; + hashCode = Utility.Verifier.GetCrc32(fileStream); + } + + if (versionList.HashCode != hashCode) + { + return false; + } + + return true; + } + catch + { + return false; + } + } + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + public TaskInfo[] GetAllLoadAssetInfos() + { + return m_ResourceLoader.GetAllLoadAssetInfos(); + } + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + public void GetAllLoadAssetInfos(List results) + { + m_ResourceLoader.GetAllLoadAssetInfos(results); + } + + /// + /// 检查资源是否存在。 + /// + /// 要检查资源的名称。 + /// 检查资源是否存在的结果。 + public HasAssetResult HasAsset(string assetName) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + return m_ResourceLoader.HasAsset(assetName); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (loadAssetCallbacks == null) + { + throw new GameFrameworkException("Load asset callbacks is invalid."); + } + + m_ResourceLoader.LoadAsset(assetName, null, Constant.DefaultPriority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, Type assetType, LoadAssetCallbacks loadAssetCallbacks) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (loadAssetCallbacks == null) + { + throw new GameFrameworkException("Load asset callbacks is invalid."); + } + + m_ResourceLoader.LoadAsset(assetName, assetType, Constant.DefaultPriority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, int priority, LoadAssetCallbacks loadAssetCallbacks) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (loadAssetCallbacks == null) + { + throw new GameFrameworkException("Load asset callbacks is invalid."); + } + + m_ResourceLoader.LoadAsset(assetName, null, priority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (loadAssetCallbacks == null) + { + throw new GameFrameworkException("Load asset callbacks is invalid."); + } + + m_ResourceLoader.LoadAsset(assetName, null, Constant.DefaultPriority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (loadAssetCallbacks == null) + { + throw new GameFrameworkException("Load asset callbacks is invalid."); + } + + m_ResourceLoader.LoadAsset(assetName, assetType, priority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, Type assetType, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (loadAssetCallbacks == null) + { + throw new GameFrameworkException("Load asset callbacks is invalid."); + } + + m_ResourceLoader.LoadAsset(assetName, assetType, Constant.DefaultPriority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (loadAssetCallbacks == null) + { + throw new GameFrameworkException("Load asset callbacks is invalid."); + } + + m_ResourceLoader.LoadAsset(assetName, null, priority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (loadAssetCallbacks == null) + { + throw new GameFrameworkException("Load asset callbacks is invalid."); + } + + m_ResourceLoader.LoadAsset(assetName, assetType, priority, loadAssetCallbacks, userData); + } + + /// + /// 卸载资源。 + /// + /// 要卸载的资源。 + public void UnloadAsset(object asset) + { + if (asset == null) + { + throw new GameFrameworkException("Asset is invalid."); + } + + if (m_ResourceLoader == null) + { + return; + } + + m_ResourceLoader.UnloadAsset(asset); + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景回调函数集。 + public void LoadScene(string sceneAssetName, LoadSceneCallbacks loadSceneCallbacks) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + if (loadSceneCallbacks == null) + { + throw new GameFrameworkException("Load scene callbacks is invalid."); + } + + m_ResourceLoader.LoadScene(sceneAssetName, Constant.DefaultPriority, loadSceneCallbacks, null); + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景资源的优先级。 + /// 加载场景回调函数集。 + public void LoadScene(string sceneAssetName, int priority, LoadSceneCallbacks loadSceneCallbacks) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + if (loadSceneCallbacks == null) + { + throw new GameFrameworkException("Load scene callbacks is invalid."); + } + + m_ResourceLoader.LoadScene(sceneAssetName, priority, loadSceneCallbacks, null); + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景回调函数集。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, LoadSceneCallbacks loadSceneCallbacks, object userData) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + if (loadSceneCallbacks == null) + { + throw new GameFrameworkException("Load scene callbacks is invalid."); + } + + m_ResourceLoader.LoadScene(sceneAssetName, Constant.DefaultPriority, loadSceneCallbacks, userData); + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景资源的优先级。 + /// 加载场景回调函数集。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, int priority, LoadSceneCallbacks loadSceneCallbacks, object userData) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + if (loadSceneCallbacks == null) + { + throw new GameFrameworkException("Load scene callbacks is invalid."); + } + + m_ResourceLoader.LoadScene(sceneAssetName, priority, loadSceneCallbacks, userData); + } + + /// + /// 异步卸载场景。 + /// + /// 要卸载场景资源的名称。 + /// 卸载场景回调函数集。 + public void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + if (unloadSceneCallbacks == null) + { + throw new GameFrameworkException("Unload scene callbacks is invalid."); + } + + m_ResourceLoader.UnloadScene(sceneAssetName, unloadSceneCallbacks, null); + } + + /// + /// 异步卸载场景。 + /// + /// 要卸载场景资源的名称。 + /// 卸载场景回调函数集。 + /// 用户自定义数据。 + public void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + if (unloadSceneCallbacks == null) + { + throw new GameFrameworkException("Unload scene callbacks is invalid."); + } + + m_ResourceLoader.UnloadScene(sceneAssetName, unloadSceneCallbacks, userData); + } + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源的实际路径。 + /// 此方法仅适用于二进制资源存储在磁盘(而非文件系统)中的情况。若二进制资源存储在文件系统中时,返回值将始终为空。 + public string GetBinaryPath(string binaryAssetName) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + return m_ResourceLoader.GetBinaryPath(binaryAssetName); + } + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源是否存储在只读区中。 + /// 二进制资源是否存储在文件系统中。 + /// 二进制资源或存储二进制资源的文件系统,相对于只读区或者读写区的相对路径。 + /// 若二进制资源存储在文件系统中,则指示二进制资源在文件系统中的名称,否则此参数返回空。 + /// 是否获取二进制资源的实际路径成功。 + public bool GetBinaryPath(string binaryAssetName, out bool storageInReadOnly, out bool storageInFileSystem, out string relativePath, out string fileName) + { + return m_ResourceLoader.GetBinaryPath(binaryAssetName, out storageInReadOnly, out storageInFileSystem, out relativePath, out fileName); + } + + /// + /// 获取二进制资源的长度。 + /// + /// 要获取长度的二进制资源的名称。 + /// 二进制资源的长度。 + public int GetBinaryLength(string binaryAssetName) + { + return m_ResourceLoader.GetBinaryLength(binaryAssetName); + } + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + public void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (loadBinaryCallbacks == null) + { + throw new GameFrameworkException("Load binary callbacks is invalid."); + } + + m_ResourceLoader.LoadBinary(binaryAssetName, loadBinaryCallbacks, null); + } + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + /// 用户自定义数据。 + public void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks, object userData) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (loadBinaryCallbacks == null) + { + throw new GameFrameworkException("Load binary callbacks is invalid."); + } + + m_ResourceLoader.LoadBinary(binaryAssetName, loadBinaryCallbacks, userData); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + public byte[] LoadBinaryFromFileSystem(string binaryAssetName) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + return m_ResourceLoader.LoadBinaryFromFileSystem(binaryAssetName); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinaryFromFileSystem(binaryAssetName, buffer, 0, buffer.Length); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinaryFromFileSystem(binaryAssetName, buffer, startIndex, buffer.Length - startIndex); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 存储加载二进制资源的二进制流的长度。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinaryFromFileSystem(binaryAssetName, buffer, startIndex, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + public byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + return m_ResourceLoader.LoadBinarySegmentFromFileSystem(binaryAssetName, 0, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + public byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + return m_ResourceLoader.LoadBinarySegmentFromFileSystem(binaryAssetName, offset, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinarySegmentFromFileSystem(binaryAssetName, 0, buffer, 0, buffer.Length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinarySegmentFromFileSystem(binaryAssetName, 0, buffer, 0, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinarySegmentFromFileSystem(binaryAssetName, 0, buffer, startIndex, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinarySegmentFromFileSystem(binaryAssetName, offset, buffer, 0, buffer.Length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinarySegmentFromFileSystem(binaryAssetName, offset, buffer, 0, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int startIndex, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + throw new GameFrameworkException("Binary asset name is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + return m_ResourceLoader.LoadBinarySegmentFromFileSystem(binaryAssetName, offset, buffer, startIndex, length); + } + + /// + /// 检查资源组是否存在。 + /// + /// 要检查资源组的名称。 + /// 资源组是否存在。 + public bool HasResourceGroup(string resourceGroupName) + { + return m_ResourceGroups.ContainsKey(resourceGroupName ?? string.Empty); + } + + /// + /// 获取默认资源组。 + /// + /// 默认资源组。 + public IResourceGroup GetResourceGroup() + { + return GetResourceGroup(string.Empty); + } + + /// + /// 获取资源组。 + /// + /// 要获取的资源组名称。 + /// 要获取的资源组。 + public IResourceGroup GetResourceGroup(string resourceGroupName) + { + ResourceGroup resourceGroup = null; + if (m_ResourceGroups.TryGetValue(resourceGroupName ?? string.Empty, out resourceGroup)) + { + return resourceGroup; + } + + return null; + } + + /// + /// 获取所有资源组。 + /// + /// 所有资源组。 + public IResourceGroup[] GetAllResourceGroups() + { + int index = 0; + IResourceGroup[] results = new IResourceGroup[m_ResourceGroups.Count]; + foreach (KeyValuePair resourceGroup in m_ResourceGroups) + { + results[index++] = resourceGroup.Value; + } + + return results; + } + + /// + /// 获取所有资源组。 + /// + /// 所有资源组。 + public void GetAllResourceGroups(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair resourceGroup in m_ResourceGroups) + { + results.Add(resourceGroup.Value); + } + } + + /// + /// 获取资源组集合。 + /// + /// 要获取的资源组名称的集合。 + /// 要获取的资源组集合。 + public IResourceGroupCollection GetResourceGroupCollection(params string[] resourceGroupNames) + { + if (resourceGroupNames == null || resourceGroupNames.Length < 1) + { + throw new GameFrameworkException("Resource group names is invalid."); + } + + ResourceGroup[] resourceGroups = new ResourceGroup[resourceGroupNames.Length]; + for (int i = 0; i < resourceGroupNames.Length; i++) + { + if (string.IsNullOrEmpty(resourceGroupNames[i])) + { + throw new GameFrameworkException("Resource group name is invalid."); + } + + resourceGroups[i] = (ResourceGroup)GetResourceGroup(resourceGroupNames[i]); + if (resourceGroups[i] == null) + { + throw new GameFrameworkException(Utility.Text.Format("Resource group '{0}' is not exist.", resourceGroupNames[i])); + } + } + + return new ResourceGroupCollection(resourceGroups, m_ResourceInfos); + } + + /// + /// 获取资源组集合。 + /// + /// 要获取的资源组名称的集合。 + /// 要获取的资源组集合。 + public IResourceGroupCollection GetResourceGroupCollection(List resourceGroupNames) + { + if (resourceGroupNames == null || resourceGroupNames.Count < 1) + { + throw new GameFrameworkException("Resource group names is invalid."); + } + + ResourceGroup[] resourceGroups = new ResourceGroup[resourceGroupNames.Count]; + for (int i = 0; i < resourceGroupNames.Count; i++) + { + if (string.IsNullOrEmpty(resourceGroupNames[i])) + { + throw new GameFrameworkException("Resource group name is invalid."); + } + + resourceGroups[i] = (ResourceGroup)GetResourceGroup(resourceGroupNames[i]); + if (resourceGroups[i] == null) + { + throw new GameFrameworkException(Utility.Text.Format("Resource group '{0}' is not exist.", resourceGroupNames[i])); + } + } + + return new ResourceGroupCollection(resourceGroups, m_ResourceInfos); + } + + private void UpdateResource(ResourceName resourceName) + { + m_ResourceUpdater.UpdateResource(resourceName); + } + + private ResourceGroup GetOrAddResourceGroup(string resourceGroupName) + { + if (resourceGroupName == null) + { + resourceGroupName = string.Empty; + } + + ResourceGroup resourceGroup = null; + if (!m_ResourceGroups.TryGetValue(resourceGroupName, out resourceGroup)) + { + resourceGroup = new ResourceGroup(resourceGroupName, m_ResourceInfos); + m_ResourceGroups.Add(resourceGroupName, resourceGroup); + } + + return resourceGroup; + } + + private AssetInfo GetAssetInfo(string assetName) + { + if (string.IsNullOrEmpty(assetName)) + { + throw new GameFrameworkException("Asset name is invalid."); + } + + if (m_AssetInfos == null) + { + return null; + } + + AssetInfo assetInfo = null; + if (m_AssetInfos.TryGetValue(assetName, out assetInfo)) + { + return assetInfo; + } + + return null; + } + + private ResourceInfo GetResourceInfo(ResourceName resourceName) + { + if (m_ResourceInfos == null) + { + return null; + } + + ResourceInfo resourceInfo = null; + if (m_ResourceInfos.TryGetValue(resourceName, out resourceInfo)) + { + return resourceInfo; + } + + return null; + } + + private IFileSystem GetFileSystem(string fileSystemName, bool storageInReadOnly) + { + if (string.IsNullOrEmpty(fileSystemName)) + { + throw new GameFrameworkException("File system name is invalid."); + } + + IFileSystem fileSystem = null; + if (storageInReadOnly) + { + if (!m_ReadOnlyFileSystems.TryGetValue(fileSystemName, out fileSystem)) + { + string fullPath = Utility.Path.GetRegularPath(Path.Combine(m_ReadOnlyPath, Utility.Text.Format("{0}.{1}", fileSystemName, DefaultExtension))); + fileSystem = m_FileSystemManager.GetFileSystem(fullPath); + if (fileSystem == null) + { + fileSystem = m_FileSystemManager.LoadFileSystem(fullPath, FileSystemAccess.Read); + m_ReadOnlyFileSystems.Add(fileSystemName, fileSystem); + } + } + } + else + { + if (!m_ReadWriteFileSystems.TryGetValue(fileSystemName, out fileSystem)) + { + string fullPath = Utility.Path.GetRegularPath(Path.Combine(m_ReadWritePath, Utility.Text.Format("{0}.{1}", fileSystemName, DefaultExtension))); + fileSystem = m_FileSystemManager.GetFileSystem(fullPath); + if (fileSystem == null) + { + if (File.Exists(fullPath)) + { + fileSystem = m_FileSystemManager.LoadFileSystem(fullPath, FileSystemAccess.ReadWrite); + } + else + { + string directory = Path.GetDirectoryName(fullPath); + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + fileSystem = m_FileSystemManager.CreateFileSystem(fullPath, FileSystemAccess.ReadWrite, FileSystemMaxFileCount, FileSystemMaxBlockCount); + } + + m_ReadWriteFileSystems.Add(fileSystemName, fileSystem); + } + } + } + + return fileSystem; + } + + private void PrepareCachedStream() + { + if (m_CachedStream == null) + { + m_CachedStream = new MemoryStream(); + } + + m_CachedStream.Position = 0L; + m_CachedStream.SetLength(0L); + } + + private void FreeCachedStream() + { + if (m_CachedStream != null) + { + m_CachedStream.Dispose(); + m_CachedStream = null; + } + } + + private void OnIniterResourceInitComplete() + { + m_ResourceIniter.ResourceInitComplete -= OnIniterResourceInitComplete; + m_ResourceIniter.Shutdown(); + m_ResourceIniter = null; + + m_InitResourcesCompleteCallback(); + m_InitResourcesCompleteCallback = null; + } + + private void OnVersionListProcessorUpdateSuccess(string downloadPath, string downloadUri) + { + m_UpdateVersionListCallbacks.UpdateVersionListSuccessCallback(downloadPath, downloadUri); + } + + private void OnVersionListProcessorUpdateFailure(string downloadUri, string errorMessage) + { + if (m_UpdateVersionListCallbacks.UpdateVersionListFailureCallback != null) + { + m_UpdateVersionListCallbacks.UpdateVersionListFailureCallback(downloadUri, errorMessage); + } + } + + private void OnVerifierResourceVerifyStart(int count, long totalLength) + { + if (m_ResourceVerifyStartEventHandler != null) + { + ResourceVerifyStartEventArgs resourceVerifyStartEventArgs = ResourceVerifyStartEventArgs.Create(count, totalLength); + m_ResourceVerifyStartEventHandler(this, resourceVerifyStartEventArgs); + ReferencePool.Release(resourceVerifyStartEventArgs); + } + } + + private void OnVerifierResourceVerifySuccess(ResourceName resourceName, int length) + { + if (m_ResourceVerifySuccessEventHandler != null) + { + ResourceVerifySuccessEventArgs resourceVerifySuccessEventArgs = ResourceVerifySuccessEventArgs.Create(resourceName.FullName, length); + m_ResourceVerifySuccessEventHandler(this, resourceVerifySuccessEventArgs); + ReferencePool.Release(resourceVerifySuccessEventArgs); + } + } + + private void OnVerifierResourceVerifyFailure(ResourceName resourceName) + { + if (m_ResourceVerifyFailureEventHandler != null) + { + ResourceVerifyFailureEventArgs resourceVerifyFailureEventArgs = ResourceVerifyFailureEventArgs.Create(resourceName.FullName); + m_ResourceVerifyFailureEventHandler(this, resourceVerifyFailureEventArgs); + ReferencePool.Release(resourceVerifyFailureEventArgs); + } + } + + private void OnVerifierResourceVerifyComplete(bool result) + { + m_VerifyResourcesCompleteCallback(result); + m_ResourceVerifier.ResourceVerifyStart -= OnVerifierResourceVerifyStart; + m_ResourceVerifier.ResourceVerifySuccess -= OnVerifierResourceVerifySuccess; + m_ResourceVerifier.ResourceVerifyFailure -= OnVerifierResourceVerifyFailure; + m_ResourceVerifier.ResourceVerifyComplete -= OnVerifierResourceVerifyComplete; + m_ResourceVerifier.Shutdown(); + m_ResourceVerifier = null; + } + + private void OnCheckerResourceNeedUpdate(ResourceName resourceName, string fileSystemName, LoadType loadType, int length, int hashCode, int compressedLength, int compressedHashCode) + { + m_ResourceUpdater.AddResourceUpdate(resourceName, fileSystemName, loadType, length, hashCode, compressedLength, compressedHashCode, Utility.Path.GetRegularPath(Path.Combine(m_ReadWritePath, resourceName.FullName))); + } + + private void OnCheckerResourceCheckComplete(int movedCount, int removedCount, int updateCount, long updateTotalLength, long updateTotalCompressedLength) + { + m_VersionListProcessor.VersionListUpdateSuccess -= OnVersionListProcessorUpdateSuccess; + m_VersionListProcessor.VersionListUpdateFailure -= OnVersionListProcessorUpdateFailure; + m_VersionListProcessor.Shutdown(); + m_VersionListProcessor = null; + m_UpdateVersionListCallbacks = null; + + m_ResourceChecker.ResourceNeedUpdate -= OnCheckerResourceNeedUpdate; + m_ResourceChecker.ResourceCheckComplete -= OnCheckerResourceCheckComplete; + m_ResourceChecker.Shutdown(); + m_ResourceChecker = null; + + m_ResourceUpdater.CheckResourceComplete(movedCount > 0 || removedCount > 0); + + if (updateCount <= 0) + { + m_ResourceUpdater.ResourceApplyStart -= OnUpdaterResourceApplyStart; + m_ResourceUpdater.ResourceApplySuccess -= OnUpdaterResourceApplySuccess; + m_ResourceUpdater.ResourceApplyFailure -= OnUpdaterResourceApplyFailure; + m_ResourceUpdater.ResourceApplyComplete -= OnUpdaterResourceApplyComplete; + m_ResourceUpdater.ResourceUpdateStart -= OnUpdaterResourceUpdateStart; + m_ResourceUpdater.ResourceUpdateChanged -= OnUpdaterResourceUpdateChanged; + m_ResourceUpdater.ResourceUpdateSuccess -= OnUpdaterResourceUpdateSuccess; + m_ResourceUpdater.ResourceUpdateFailure -= OnUpdaterResourceUpdateFailure; + m_ResourceUpdater.ResourceUpdateComplete -= OnUpdaterResourceUpdateComplete; + m_ResourceUpdater.ResourceUpdateAllComplete -= OnUpdaterResourceUpdateAllComplete; + m_ResourceUpdater.Shutdown(); + m_ResourceUpdater = null; + + m_ReadWriteResourceInfos.Clear(); + m_ReadWriteResourceInfos = null; + + FreeCachedStream(); + } + + m_CheckResourcesCompleteCallback(movedCount, removedCount, updateCount, updateTotalLength, updateTotalCompressedLength); + m_CheckResourcesCompleteCallback = null; + } + + private void OnUpdaterResourceApplyStart(string resourcePackPath, int count, long totalLength) + { + if (m_ResourceApplyStartEventHandler != null) + { + ResourceApplyStartEventArgs resourceApplyStartEventArgs = ResourceApplyStartEventArgs.Create(resourcePackPath, count, totalLength); + m_ResourceApplyStartEventHandler(this, resourceApplyStartEventArgs); + ReferencePool.Release(resourceApplyStartEventArgs); + } + } + + private void OnUpdaterResourceApplySuccess(ResourceName resourceName, string applyPath, string resourcePackPath, int length, int compressedLength) + { + if (m_ResourceApplySuccessEventHandler != null) + { + ResourceApplySuccessEventArgs resourceApplySuccessEventArgs = ResourceApplySuccessEventArgs.Create(resourceName.FullName, applyPath, resourcePackPath, length, compressedLength); + m_ResourceApplySuccessEventHandler(this, resourceApplySuccessEventArgs); + ReferencePool.Release(resourceApplySuccessEventArgs); + } + } + + private void OnUpdaterResourceApplyFailure(ResourceName resourceName, string resourcePackPath, string errorMessage) + { + if (m_ResourceApplyFailureEventHandler != null) + { + ResourceApplyFailureEventArgs resourceApplyFailureEventArgs = ResourceApplyFailureEventArgs.Create(resourceName.FullName, resourcePackPath, errorMessage); + m_ResourceApplyFailureEventHandler(this, resourceApplyFailureEventArgs); + ReferencePool.Release(resourceApplyFailureEventArgs); + } + } + + private void OnUpdaterResourceApplyComplete(string resourcePackPath, bool result) + { + ApplyResourcesCompleteCallback applyResourcesCompleteCallback = m_ApplyResourcesCompleteCallback; + m_ApplyResourcesCompleteCallback = null; + applyResourcesCompleteCallback(resourcePackPath, result); + } + + private void OnUpdaterResourceUpdateStart(ResourceName resourceName, string downloadPath, string downloadUri, int currentLength, int compressedLength, int retryCount) + { + if (m_ResourceUpdateStartEventHandler != null) + { + ResourceUpdateStartEventArgs resourceUpdateStartEventArgs = ResourceUpdateStartEventArgs.Create(resourceName.FullName, downloadPath, downloadUri, currentLength, compressedLength, retryCount); + m_ResourceUpdateStartEventHandler(this, resourceUpdateStartEventArgs); + ReferencePool.Release(resourceUpdateStartEventArgs); + } + } + + private void OnUpdaterResourceUpdateChanged(ResourceName resourceName, string downloadPath, string downloadUri, int currentLength, int compressedLength) + { + if (m_ResourceUpdateChangedEventHandler != null) + { + ResourceUpdateChangedEventArgs resourceUpdateChangedEventArgs = ResourceUpdateChangedEventArgs.Create(resourceName.FullName, downloadPath, downloadUri, currentLength, compressedLength); + m_ResourceUpdateChangedEventHandler(this, resourceUpdateChangedEventArgs); + ReferencePool.Release(resourceUpdateChangedEventArgs); + } + } + + private void OnUpdaterResourceUpdateSuccess(ResourceName resourceName, string downloadPath, string downloadUri, int length, int compressedLength) + { + if (m_ResourceUpdateSuccessEventHandler != null) + { + ResourceUpdateSuccessEventArgs resourceUpdateSuccessEventArgs = ResourceUpdateSuccessEventArgs.Create(resourceName.FullName, downloadPath, downloadUri, length, compressedLength); + m_ResourceUpdateSuccessEventHandler(this, resourceUpdateSuccessEventArgs); + ReferencePool.Release(resourceUpdateSuccessEventArgs); + } + } + + private void OnUpdaterResourceUpdateFailure(ResourceName resourceName, string downloadUri, int retryCount, int totalRetryCount, string errorMessage) + { + if (m_ResourceUpdateFailureEventHandler != null) + { + ResourceUpdateFailureEventArgs resourceUpdateFailureEventArgs = ResourceUpdateFailureEventArgs.Create(resourceName.FullName, downloadUri, retryCount, totalRetryCount, errorMessage); + m_ResourceUpdateFailureEventHandler(this, resourceUpdateFailureEventArgs); + ReferencePool.Release(resourceUpdateFailureEventArgs); + } + } + + private void OnUpdaterResourceUpdateComplete(ResourceGroup resourceGroup, bool result) + { + Utility.Path.RemoveEmptyDirectory(m_ReadWritePath); + UpdateResourcesCompleteCallback updateResourcesCompleteCallback = m_UpdateResourcesCompleteCallback; + m_UpdateResourcesCompleteCallback = null; + updateResourcesCompleteCallback(resourceGroup, result); + } + + private void OnUpdaterResourceUpdateAllComplete() + { + m_ResourceUpdater.ResourceApplyStart -= OnUpdaterResourceApplyStart; + m_ResourceUpdater.ResourceApplySuccess -= OnUpdaterResourceApplySuccess; + m_ResourceUpdater.ResourceApplyFailure -= OnUpdaterResourceApplyFailure; + m_ResourceUpdater.ResourceApplyComplete -= OnUpdaterResourceApplyComplete; + m_ResourceUpdater.ResourceUpdateStart -= OnUpdaterResourceUpdateStart; + m_ResourceUpdater.ResourceUpdateChanged -= OnUpdaterResourceUpdateChanged; + m_ResourceUpdater.ResourceUpdateSuccess -= OnUpdaterResourceUpdateSuccess; + m_ResourceUpdater.ResourceUpdateFailure -= OnUpdaterResourceUpdateFailure; + m_ResourceUpdater.ResourceUpdateComplete -= OnUpdaterResourceUpdateComplete; + m_ResourceUpdater.ResourceUpdateAllComplete -= OnUpdaterResourceUpdateAllComplete; + m_ResourceUpdater.Shutdown(); + m_ResourceUpdater = null; + + m_ReadWriteResourceInfos.Clear(); + m_ReadWriteResourceInfos = null; + + FreeCachedStream(); + Utility.Path.RemoveEmptyDirectory(m_ReadWritePath); + + if (m_ResourceUpdateAllCompleteEventHandler != null) + { + ResourceUpdateAllCompleteEventArgs resourceUpdateAllCompleteEventArgs = ResourceUpdateAllCompleteEventArgs.Create(); + m_ResourceUpdateAllCompleteEventHandler(this, resourceUpdateAllCompleteEventArgs); + ReferencePool.Release(resourceUpdateAllCompleteEventArgs); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.cs.meta new file mode 100644 index 0000000..87431e3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a6bdb3e805060d4fa081fbb5f510adb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceMode.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceMode.cs new file mode 100644 index 0000000..5499382 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceMode.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源模式。 + /// + public enum ResourceMode : byte + { + /// + /// 未指定。 + /// + Unspecified = 0, + + /// + /// 单机模式。 + /// + Package, + + /// + /// 预下载的可更新模式。 + /// + Updatable, + + /// + /// 使用时下载的可更新模式。 + /// + UpdatableWhilePlaying + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceMode.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceMode.cs.meta new file mode 100644 index 0000000..c73155f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 302553b9c2d30284f80ab533caa2354f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.Resource.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.Resource.cs new file mode 100644 index 0000000..ca09125 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.Resource.cs @@ -0,0 +1,160 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct ResourcePackVersionList + { + /// + /// 资源。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Resource + { + private readonly string m_Name; + private readonly string m_Variant; + private readonly string m_Extension; + private readonly byte m_LoadType; + private readonly long m_Offset; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly int m_CompressedLength; + private readonly int m_CompressedHashCode; + + /// + /// 初始化资源的新实例。 + /// + /// 资源名称。 + /// 资源变体名称。 + /// 资源扩展名称。 + /// 资源加载方式。 + /// 资源偏移。 + /// 资源长度。 + /// 资源哈希值。 + /// 资源压缩后长度。 + /// 资源压缩后哈希值。 + public Resource(string name, string variant, string extension, byte loadType, long offset, int length, int hashCode, int compressedLength, int compressedHashCode) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_Variant = variant; + m_Extension = extension; + m_LoadType = loadType; + m_Offset = offset; + m_Length = length; + m_HashCode = hashCode; + m_CompressedLength = compressedLength; + m_CompressedHashCode = compressedHashCode; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源变体名称。 + /// + public string Variant + { + get + { + return m_Variant; + } + } + + /// + /// 获取资源扩展名称。 + /// + public string Extension + { + get + { + return m_Extension; + } + } + + /// + /// 获取资源加载方式。 + /// + public byte LoadType + { + get + { + return m_LoadType; + } + } + + /// + /// 获取资源偏移。 + /// + public long Offset + { + get + { + return m_Offset; + } + } + + /// + /// 获取资源长度。 + /// + public int Length + { + get + { + return m_Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_HashCode; + } + } + + /// + /// 获取资源压缩后长度。 + /// + public int CompressedLength + { + get + { + return m_CompressedLength; + } + } + + /// + /// 获取资源压缩后哈希值。 + /// + public int CompressedHashCode + { + get + { + return m_CompressedHashCode; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.Resource.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.Resource.cs.meta new file mode 100644 index 0000000..8b5915e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.Resource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b540dcc246e54364ca91c734bb3e3eed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.cs new file mode 100644 index 0000000..ef89148 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.cs @@ -0,0 +1,115 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + /// + /// 资源包版本资源列表。 + /// + [StructLayout(LayoutKind.Auto)] + public partial struct ResourcePackVersionList + { + private static readonly Resource[] EmptyResourceArray = new Resource[] { }; + + private readonly bool m_IsValid; + private readonly int m_Offset; + private readonly long m_Length; + private readonly int m_HashCode; + private readonly Resource[] m_Resources; + + /// + /// 初始化资源包版本资源列表的新实例。 + /// + /// 资源数据偏移。 + /// 资源数据长度。 + /// 资源数据哈希值。 + /// 包含的资源集合。 + public ResourcePackVersionList(int offset, long length, int hashCode, Resource[] resources) + { + m_IsValid = true; + m_Offset = offset; + m_Length = length; + m_HashCode = hashCode; + m_Resources = resources ?? EmptyResourceArray; + } + + /// + /// 获取资源包版本资源列表是否有效。 + /// + public bool IsValid + { + get + { + return m_IsValid; + } + } + + /// + /// 获取资源数据偏移。 + /// + public int Offset + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Offset; + } + } + + /// + /// 获取资源数据长度。 + /// + public long Length + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Length; + } + } + + /// + /// 获取资源数据哈希值。 + /// + public int HashCode + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_HashCode; + } + } + + /// + /// 获取包含的资源集合。 + /// + /// 包含的资源集合。 + public Resource[] GetResources() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Resources; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.cs.meta new file mode 100644 index 0000000..332a0ad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f5f11c3d85778c24ca7f095f197c804a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionListSerializer.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionListSerializer.cs new file mode 100644 index 0000000..539b8d7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionListSerializer.cs @@ -0,0 +1,33 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源包版本资源列表序列化器。 + /// + public sealed class ResourcePackVersionListSerializer : GameFrameworkSerializer + { + private static readonly byte[] Header = new byte[] { (byte)'G', (byte)'F', (byte)'K' }; + + /// + /// 初始化资源包版本资源列表序列化器的新实例。 + /// + public ResourcePackVersionListSerializer() + { + } + + /// + /// 获取资源包版本资源列表头标识。 + /// + /// 资源包版本资源列表头标识。 + protected override byte[] GetHeader() + { + return Header; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionListSerializer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionListSerializer.cs.meta new file mode 100644 index 0000000..9e749e4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourcePackVersionListSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cbe6806a0d53dd34a956efa339af1931 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs new file mode 100644 index 0000000..1be8522 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源更新全部完成事件。 + /// + public sealed class ResourceUpdateAllCompleteEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源更新全部完成事件的新实例。 + /// + public ResourceUpdateAllCompleteEventArgs() + { + } + + /// + /// 创建资源更新全部完成事件。 + /// + /// 创建的资源更新全部完成事件。 + public static ResourceUpdateAllCompleteEventArgs Create() + { + return ReferencePool.Acquire(); + } + + /// + /// 清理资源更新全部完成事件。 + /// + public override void Clear() + { + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs.meta new file mode 100644 index 0000000..ad52bff --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2cca8bba99d79a4e994a852a63e48b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateChangedEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateChangedEventArgs.cs new file mode 100644 index 0000000..4c99008 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateChangedEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源更新改变事件。 + /// + public sealed class ResourceUpdateChangedEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源更新改变事件的新实例。 + /// + public ResourceUpdateChangedEventArgs() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0; + CompressedLength = 0; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前下载大小。 + /// + public int CurrentLength + { + get; + private set; + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get; + private set; + } + + /// + /// 创建资源更新改变事件。 + /// + /// 资源名称。 + /// 资源下载后存放路径。 + /// 资源下载地址。 + /// 当前下载大小。 + /// 压缩后大小。 + /// 创建的资源更新改变事件。 + public static ResourceUpdateChangedEventArgs Create(string name, string downloadPath, string downloadUri, int currentLength, int compressedLength) + { + ResourceUpdateChangedEventArgs resourceUpdateChangedEventArgs = ReferencePool.Acquire(); + resourceUpdateChangedEventArgs.Name = name; + resourceUpdateChangedEventArgs.DownloadPath = downloadPath; + resourceUpdateChangedEventArgs.DownloadUri = downloadUri; + resourceUpdateChangedEventArgs.CurrentLength = currentLength; + resourceUpdateChangedEventArgs.CompressedLength = compressedLength; + return resourceUpdateChangedEventArgs; + } + + /// + /// 清理资源更新改变事件。 + /// + public override void Clear() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0; + CompressedLength = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateChangedEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateChangedEventArgs.cs.meta new file mode 100644 index 0000000..621bb33 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateChangedEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3069a06720a3f464e90175c56c912adc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateFailureEventArgs.cs new file mode 100644 index 0000000..544e884 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateFailureEventArgs.cs @@ -0,0 +1,105 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源更新失败事件。 + /// + public sealed class ResourceUpdateFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源更新失败事件的新实例。 + /// + public ResourceUpdateFailureEventArgs() + { + Name = null; + DownloadUri = null; + RetryCount = 0; + TotalRetryCount = 0; + ErrorMessage = null; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取已重试次数。 + /// + public int RetryCount + { + get; + private set; + } + + /// + /// 获取设定的重试次数。 + /// + public int TotalRetryCount + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建资源更新失败事件。 + /// + /// 资源名称。 + /// 下载地址。 + /// 已重试次数。 + /// 设定的重试次数。 + /// 错误信息。 + /// 创建的资源更新失败事件。 + /// 当已重试次数达到设定的重试次数时,将不再重试。 + public static ResourceUpdateFailureEventArgs Create(string name, string downloadUri, int retryCount, int totalRetryCount, string errorMessage) + { + ResourceUpdateFailureEventArgs resourceUpdateFailureEventArgs = ReferencePool.Acquire(); + resourceUpdateFailureEventArgs.Name = name; + resourceUpdateFailureEventArgs.DownloadUri = downloadUri; + resourceUpdateFailureEventArgs.RetryCount = retryCount; + resourceUpdateFailureEventArgs.TotalRetryCount = totalRetryCount; + resourceUpdateFailureEventArgs.ErrorMessage = errorMessage; + return resourceUpdateFailureEventArgs; + } + + /// + /// 清理资源更新失败事件。 + /// + public override void Clear() + { + Name = null; + DownloadUri = null; + RetryCount = 0; + TotalRetryCount = 0; + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateFailureEventArgs.cs.meta new file mode 100644 index 0000000..20a94fd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d748e11461c165340ba74d170e41b35e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateStartEventArgs.cs new file mode 100644 index 0000000..0f4d9ae --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateStartEventArgs.cs @@ -0,0 +1,117 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源更新开始事件。 + /// + public sealed class ResourceUpdateStartEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源更新开始事件的新实例。 + /// + public ResourceUpdateStartEventArgs() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0; + CompressedLength = 0; + RetryCount = 0; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前下载大小。 + /// + public int CurrentLength + { + get; + private set; + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get; + private set; + } + + /// + /// 获取已重试下载次数。 + /// + public int RetryCount + { + get; + private set; + } + + /// + /// 创建资源更新开始事件。 + /// + /// 资源名称。 + /// 资源下载后存放路径。 + /// 资源下载地址。 + /// 当前下载大小。 + /// 压缩后大小。 + /// 已重试下载次数。 + /// 创建的资源更新开始事件。 + public static ResourceUpdateStartEventArgs Create(string name, string downloadPath, string downloadUri, int currentLength, int compressedLength, int retryCount) + { + ResourceUpdateStartEventArgs resourceUpdateStartEventArgs = ReferencePool.Acquire(); + resourceUpdateStartEventArgs.Name = name; + resourceUpdateStartEventArgs.DownloadPath = downloadPath; + resourceUpdateStartEventArgs.DownloadUri = downloadUri; + resourceUpdateStartEventArgs.CurrentLength = currentLength; + resourceUpdateStartEventArgs.CompressedLength = compressedLength; + resourceUpdateStartEventArgs.RetryCount = retryCount; + return resourceUpdateStartEventArgs; + } + + /// + /// 清理资源更新开始事件。 + /// + public override void Clear() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0; + CompressedLength = 0; + RetryCount = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateStartEventArgs.cs.meta new file mode 100644 index 0000000..25c38e3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f2893c8378bc574c838de164dcdaab8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateSuccessEventArgs.cs new file mode 100644 index 0000000..3894a5c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateSuccessEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源更新成功事件。 + /// + public sealed class ResourceUpdateSuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源更新成功事件的新实例。 + /// + public ResourceUpdateSuccessEventArgs() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + Length = 0; + CompressedLength = 0; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get; + private set; + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get; + private set; + } + + /// + /// 创建资源更新成功事件。 + /// + /// 资源名称。 + /// 资源下载后存放路径。 + /// 资源下载地址。 + /// 资源大小。 + /// 压缩后大小。 + /// 创建的资源更新成功事件。 + public static ResourceUpdateSuccessEventArgs Create(string name, string downloadPath, string downloadUri, int length, int compressedLength) + { + ResourceUpdateSuccessEventArgs resourceUpdateSuccessEventArgs = ReferencePool.Acquire(); + resourceUpdateSuccessEventArgs.Name = name; + resourceUpdateSuccessEventArgs.DownloadPath = downloadPath; + resourceUpdateSuccessEventArgs.DownloadUri = downloadUri; + resourceUpdateSuccessEventArgs.Length = length; + resourceUpdateSuccessEventArgs.CompressedLength = compressedLength; + return resourceUpdateSuccessEventArgs; + } + + /// + /// 清理资源更新成功事件。 + /// + public override void Clear() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + Length = 0; + CompressedLength = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateSuccessEventArgs.cs.meta new file mode 100644 index 0000000..dbdc29d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceUpdateSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83709c18daf7de44ebd1791eaa780eaf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyFailureEventArgs.cs new file mode 100644 index 0000000..efaaef1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyFailureEventArgs.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源校验失败事件。 + /// + public sealed class ResourceVerifyFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源校验失败事件的新实例。 + /// + public ResourceVerifyFailureEventArgs() + { + Name = null; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 创建资源校验失败事件。 + /// + /// 资源名称。 + /// 创建的资源校验失败事件。 + public static ResourceVerifyFailureEventArgs Create(string name) + { + ResourceVerifyFailureEventArgs resourceVerifyFailureEventArgs = ReferencePool.Acquire(); + resourceVerifyFailureEventArgs.Name = name; + return resourceVerifyFailureEventArgs; + } + + /// + /// 清理资源校验失败事件。 + /// + public override void Clear() + { + Name = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyFailureEventArgs.cs.meta new file mode 100644 index 0000000..249b6ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3595033b3cc1ffc49bf98d42fba4fdf8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyStartEventArgs.cs new file mode 100644 index 0000000..9c3e3bd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyStartEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源校验开始事件。 + /// + public sealed class ResourceVerifyStartEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源校验开始事件的新实例。 + /// + public ResourceVerifyStartEventArgs() + { + Count = 0; + TotalLength = 0L; + } + + /// + /// 获取要校验资源的数量。 + /// + public int Count + { + get; + private set; + } + + /// + /// 获取要校验资源的总大小。 + /// + public long TotalLength + { + get; + private set; + } + + /// + /// 创建资源校验开始事件。 + /// + /// 要校验资源的数量。 + /// 要校验资源的总大小。 + /// 创建的资源校验开始事件。 + public static ResourceVerifyStartEventArgs Create(int count, long totalLength) + { + ResourceVerifyStartEventArgs resourceVerifyStartEventArgs = ReferencePool.Acquire(); + resourceVerifyStartEventArgs.Count = count; + resourceVerifyStartEventArgs.TotalLength = totalLength; + return resourceVerifyStartEventArgs; + } + + /// + /// 清理资源校验开始事件。 + /// + public override void Clear() + { + Count = 0; + TotalLength = 0L; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyStartEventArgs.cs.meta new file mode 100644 index 0000000..f6b3361 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifyStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eec34bb9d218a354cbe2d80e913775c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifySuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifySuccessEventArgs.cs new file mode 100644 index 0000000..4557f8a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifySuccessEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 资源校验成功事件。 + /// + public sealed class ResourceVerifySuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化资源校验成功事件的新实例。 + /// + public ResourceVerifySuccessEventArgs() + { + Name = null; + Length = 0; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get; + private set; + } + + /// + /// 创建资源校验成功事件。 + /// + /// 资源名称。 + /// 资源大小。 + /// 创建的资源校验成功事件。 + public static ResourceVerifySuccessEventArgs Create(string name, int length) + { + ResourceVerifySuccessEventArgs resourceVerifySuccessEventArgs = ReferencePool.Acquire(); + resourceVerifySuccessEventArgs.Name = name; + resourceVerifySuccessEventArgs.Length = length; + return resourceVerifySuccessEventArgs; + } + + /// + /// 清理资源校验成功事件。 + /// + public override void Clear() + { + Name = null; + Length = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifySuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifySuccessEventArgs.cs.meta new file mode 100644 index 0000000..5c07f10 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/ResourceVerifySuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7d1c4ad05456f0428c3918407bee429 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneCallbacks.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneCallbacks.cs new file mode 100644 index 0000000..24bc510 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneCallbacks.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 卸载场景回调函数集。 + /// + public sealed class UnloadSceneCallbacks + { + private readonly UnloadSceneSuccessCallback m_UnloadSceneSuccessCallback; + private readonly UnloadSceneFailureCallback m_UnloadSceneFailureCallback; + + /// + /// 初始化卸载场景回调函数集的新实例。 + /// + /// 卸载场景成功回调函数。 + public UnloadSceneCallbacks(UnloadSceneSuccessCallback unloadSceneSuccessCallback) + : this(unloadSceneSuccessCallback, null) + { + } + + /// + /// 初始化卸载场景回调函数集的新实例。 + /// + /// 卸载场景成功回调函数。 + /// 卸载场景失败回调函数。 + public UnloadSceneCallbacks(UnloadSceneSuccessCallback unloadSceneSuccessCallback, UnloadSceneFailureCallback unloadSceneFailureCallback) + { + if (unloadSceneSuccessCallback == null) + { + throw new GameFrameworkException("Unload scene success callback is invalid."); + } + + m_UnloadSceneSuccessCallback = unloadSceneSuccessCallback; + m_UnloadSceneFailureCallback = unloadSceneFailureCallback; + } + + /// + /// 获取卸载场景成功回调函数。 + /// + public UnloadSceneSuccessCallback UnloadSceneSuccessCallback + { + get + { + return m_UnloadSceneSuccessCallback; + } + } + + /// + /// 获取卸载场景失败回调函数。 + /// + public UnloadSceneFailureCallback UnloadSceneFailureCallback + { + get + { + return m_UnloadSceneFailureCallback; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneCallbacks.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneCallbacks.cs.meta new file mode 100644 index 0000000..fe3cefd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16eebecd11e81764082559a656aabd21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneFailureCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneFailureCallback.cs new file mode 100644 index 0000000..5c62a76 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneFailureCallback.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 卸载场景失败回调函数。 + /// + /// 要卸载的场景资源名称。 + /// 用户自定义数据。 + public delegate void UnloadSceneFailureCallback(string sceneAssetName, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneFailureCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneFailureCallback.cs.meta new file mode 100644 index 0000000..c6ead2d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneFailureCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8fff37bd72a4844198601d893648cbd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneSuccessCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneSuccessCallback.cs new file mode 100644 index 0000000..4337db1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneSuccessCallback.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 卸载场景成功回调函数。 + /// + /// 要卸载的场景资源名称。 + /// 用户自定义数据。 + public delegate void UnloadSceneSuccessCallback(string sceneAssetName, object userData); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneSuccessCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneSuccessCallback.cs.meta new file mode 100644 index 0000000..7452ee1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UnloadSceneSuccessCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91f99543ee266b84f939b476fefa52ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Asset.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Asset.cs new file mode 100644 index 0000000..89b976e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Asset.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct UpdatableVersionList + { + /// + /// 资源。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Asset + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly int[] m_DependencyAssetIndexes; + + /// + /// 初始化资源的新实例。 + /// + /// 资源名称。 + /// 资源包含的依赖资源索引集合。 + public Asset(string name, int[] dependencyAssetIndexes) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_DependencyAssetIndexes = dependencyAssetIndexes ?? EmptyIntArray; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源包含的依赖资源索引集合。 + /// + /// 资源包含的依赖资源索引集合。 + public int[] GetDependencyAssetIndexes() + { + return m_DependencyAssetIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Asset.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Asset.cs.meta new file mode 100644 index 0000000..fbcf37f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Asset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d8ff3eef3791174e8451f2bdd3bf5d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.FileSystem.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.FileSystem.cs new file mode 100644 index 0000000..bd28196 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.FileSystem.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct UpdatableVersionList + { + /// + /// 文件系统。 + /// + [StructLayout(LayoutKind.Auto)] + public struct FileSystem + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly int[] m_ResourceIndexes; + + /// + /// 初始化文件系统的新实例。 + /// + /// 文件系统名称。 + /// 文件系统包含的资源索引集合。 + public FileSystem(string name, int[] resourceIndexes) + { + if (name == null) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_ResourceIndexes = resourceIndexes ?? EmptyIntArray; + } + + /// + /// 获取文件系统名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取文件系统包含的资源索引集合。 + /// + /// 文件系统包含的资源索引集合。 + public int[] GetResourceIndexes() + { + return m_ResourceIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.FileSystem.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.FileSystem.cs.meta new file mode 100644 index 0000000..1556cd9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.FileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a4ddd9d123080534cb096b037df42620 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Resource.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Resource.cs new file mode 100644 index 0000000..b4eceaf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Resource.cs @@ -0,0 +1,160 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct UpdatableVersionList + { + /// + /// 资源。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Resource + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly string m_Variant; + private readonly string m_Extension; + private readonly byte m_LoadType; + private readonly int m_Length; + private readonly int m_HashCode; + private readonly int m_CompressedLength; + private readonly int m_CompressedHashCode; + private readonly int[] m_AssetIndexes; + + /// + /// 初始化资源的新实例。 + /// + /// 资源名称。 + /// 资源变体名称。 + /// 资源扩展名称。 + /// 资源加载方式。 + /// 资源长度。 + /// 资源哈希值。 + /// 资源压缩后长度。 + /// 资源压缩后哈希值。 + /// 资源包含的资源索引集合。 + public Resource(string name, string variant, string extension, byte loadType, int length, int hashCode, int compressedLength, int compressedHashCode, int[] assetIndexes) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_Variant = variant; + m_Extension = extension; + m_LoadType = loadType; + m_Length = length; + m_HashCode = hashCode; + m_CompressedLength = compressedLength; + m_CompressedHashCode = compressedHashCode; + m_AssetIndexes = assetIndexes ?? EmptyIntArray; + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源变体名称。 + /// + public string Variant + { + get + { + return m_Variant; + } + } + + /// + /// 获取资源扩展名称。 + /// + public string Extension + { + get + { + return m_Extension; + } + } + + /// + /// 获取资源加载方式。 + /// + public byte LoadType + { + get + { + return m_LoadType; + } + } + + /// + /// 获取资源长度。 + /// + public int Length + { + get + { + return m_Length; + } + } + + /// + /// 获取资源哈希值。 + /// + public int HashCode + { + get + { + return m_HashCode; + } + } + + /// + /// 获取资源压缩后长度。 + /// + public int CompressedLength + { + get + { + return m_CompressedLength; + } + } + + /// + /// 获取资源压缩后哈希值。 + /// + public int CompressedHashCode + { + get + { + return m_CompressedHashCode; + } + } + + /// + /// 获取资源包含的资源索引集合。 + /// + /// 资源包含的资源索引集合。 + public int[] GetAssetIndexes() + { + return m_AssetIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Resource.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Resource.cs.meta new file mode 100644 index 0000000..84f3ba3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.Resource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56fd3ce6bf410be409ab3d0593a134e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.ResourceGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.ResourceGroup.cs new file mode 100644 index 0000000..b0df9f8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.ResourceGroup.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + public partial struct UpdatableVersionList + { + /// + /// 资源组。 + /// + [StructLayout(LayoutKind.Auto)] + public struct ResourceGroup + { + private static readonly int[] EmptyIntArray = new int[] { }; + + private readonly string m_Name; + private readonly int[] m_ResourceIndexes; + + /// + /// 初始化资源组的新实例。 + /// + /// 资源组名称。 + /// 资源组包含的资源索引集合。 + public ResourceGroup(string name, int[] resourceIndexes) + { + if (name == null) + { + throw new GameFrameworkException("Name is invalid."); + } + + m_Name = name; + m_ResourceIndexes = resourceIndexes ?? EmptyIntArray; + } + + /// + /// 获取资源组名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取资源组包含的资源索引集合。 + /// + /// 资源组包含的资源索引集合。 + public int[] GetResourceIndexes() + { + return m_ResourceIndexes; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.ResourceGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.ResourceGroup.cs.meta new file mode 100644 index 0000000..71ef3c2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.ResourceGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a244462a671085b48bd704e016c286d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.cs new file mode 100644 index 0000000..e8f908d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.cs @@ -0,0 +1,150 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Runtime.InteropServices; + +namespace GameFramework.Resource +{ + /// + /// 可更新模式版本资源列表。 + /// + [StructLayout(LayoutKind.Auto)] + public partial struct UpdatableVersionList + { + private static readonly Asset[] EmptyAssetArray = new Asset[] { }; + private static readonly Resource[] EmptyResourceArray = new Resource[] { }; + private static readonly FileSystem[] EmptyFileSystemArray = new FileSystem[] { }; + private static readonly ResourceGroup[] EmptyResourceGroupArray = new ResourceGroup[] { }; + + private readonly bool m_IsValid; + private readonly string m_ApplicableGameVersion; + private readonly int m_InternalResourceVersion; + private readonly Asset[] m_Assets; + private readonly Resource[] m_Resources; + private readonly FileSystem[] m_FileSystems; + private readonly ResourceGroup[] m_ResourceGroups; + + /// + /// 初始化可更新模式版本资源列表的新实例。 + /// + /// 适配的游戏版本号。 + /// 内部资源版本号。 + /// 包含的资源集合。 + /// 包含的资源集合。 + /// 包含的文件系统集合。 + /// 包含的资源组集合。 + public UpdatableVersionList(string applicableGameVersion, int internalResourceVersion, Asset[] assets, Resource[] resources, FileSystem[] fileSystems, ResourceGroup[] resourceGroups) + { + m_IsValid = true; + m_ApplicableGameVersion = applicableGameVersion; + m_InternalResourceVersion = internalResourceVersion; + m_Assets = assets ?? EmptyAssetArray; + m_Resources = resources ?? EmptyResourceArray; + m_FileSystems = fileSystems ?? EmptyFileSystemArray; + m_ResourceGroups = resourceGroups ?? EmptyResourceGroupArray; + } + + /// + /// 获取可更新模式版本资源列表是否有效。 + /// + public bool IsValid + { + get + { + return m_IsValid; + } + } + + /// + /// 获取适配的游戏版本号。 + /// + public string ApplicableGameVersion + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_ApplicableGameVersion; + } + } + + /// + /// 获取内部资源版本号。 + /// + public int InternalResourceVersion + { + get + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_InternalResourceVersion; + } + } + + /// + /// 获取包含的资源集合。 + /// + /// 包含的资源集合。 + public Asset[] GetAssets() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Assets; + } + + /// + /// 获取包含的资源集合。 + /// + /// 包含的资源集合。 + public Resource[] GetResources() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_Resources; + } + + /// + /// 获取包含的文件系统集合。 + /// + /// 包含的文件系统集合。 + public FileSystem[] GetFileSystems() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_FileSystems; + } + + /// + /// 获取包含的资源组集合。 + /// + /// 包含的资源组集合。 + public ResourceGroup[] GetResourceGroups() + { + if (!m_IsValid) + { + throw new GameFrameworkException("Data is invalid."); + } + + return m_ResourceGroups; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.cs.meta new file mode 100644 index 0000000..09140fb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a1727e5e57f9b24e8b6fee68216484e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionListSerializer.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionListSerializer.cs new file mode 100644 index 0000000..2ea4bbc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionListSerializer.cs @@ -0,0 +1,33 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 可更新模式版本资源列表序列化器。 + /// + public sealed class UpdatableVersionListSerializer : GameFrameworkSerializer + { + private static readonly byte[] Header = new byte[] { (byte)'G', (byte)'F', (byte)'U' }; + + /// + /// 初始化可更新模式版本资源列表序列化器的新实例。 + /// + public UpdatableVersionListSerializer() + { + } + + /// + /// 获取可更新模式版本资源列表头标识。 + /// + /// 可更新模式版本资源列表头标识。 + protected override byte[] GetHeader() + { + return Header; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionListSerializer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionListSerializer.cs.meta new file mode 100644 index 0000000..ca15d71 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdatableVersionListSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a4e3f11bb04fb94b8cec16d5b44877a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateResourcesCompleteCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateResourcesCompleteCallback.cs new file mode 100644 index 0000000..5c26ce5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateResourcesCompleteCallback.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 使用可更新模式并更新指定资源组完成时的回调函数。 + /// + /// 更新的资源组。 + /// 更新资源结果,全部成功为 true,否则为 false。 + public delegate void UpdateResourcesCompleteCallback(IResourceGroup resourceGroup, bool result); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateResourcesCompleteCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateResourcesCompleteCallback.cs.meta new file mode 100644 index 0000000..c8b730c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateResourcesCompleteCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d417741194db8cc489d40e0600f8f7b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListCallbacks.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListCallbacks.cs new file mode 100644 index 0000000..89d9f5e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListCallbacks.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 版本资源列表更新回调函数集。 + /// + public sealed class UpdateVersionListCallbacks + { + private readonly UpdateVersionListSuccessCallback m_UpdateVersionListSuccessCallback; + private readonly UpdateVersionListFailureCallback m_UpdateVersionListFailureCallback; + + /// + /// 初始化版本资源列表更新回调函数集的新实例。 + /// + /// 版本资源列表更新成功回调函数。 + public UpdateVersionListCallbacks(UpdateVersionListSuccessCallback updateVersionListSuccessCallback) + : this(updateVersionListSuccessCallback, null) + { + } + + /// + /// 初始化版本资源列表更新回调函数集的新实例。 + /// + /// 版本资源列表更新成功回调函数。 + /// 版本资源列表更新失败回调函数。 + public UpdateVersionListCallbacks(UpdateVersionListSuccessCallback updateVersionListSuccessCallback, UpdateVersionListFailureCallback updateVersionListFailureCallback) + { + if (updateVersionListSuccessCallback == null) + { + throw new GameFrameworkException("Update version list success callback is invalid."); + } + + m_UpdateVersionListSuccessCallback = updateVersionListSuccessCallback; + m_UpdateVersionListFailureCallback = updateVersionListFailureCallback; + } + + /// + /// 获取版本资源列表更新成功回调函数。 + /// + public UpdateVersionListSuccessCallback UpdateVersionListSuccessCallback + { + get + { + return m_UpdateVersionListSuccessCallback; + } + } + + /// + /// 获取版本资源列表更新失败回调函数。 + /// + public UpdateVersionListFailureCallback UpdateVersionListFailureCallback + { + get + { + return m_UpdateVersionListFailureCallback; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListCallbacks.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListCallbacks.cs.meta new file mode 100644 index 0000000..4619be7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0e27d2f388225246b155dff1a9c4252 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListFailureCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListFailureCallback.cs new file mode 100644 index 0000000..e2f32ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListFailureCallback.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 版本资源列表更新失败回调函数。 + /// + /// 版本资源列表更新地址。 + /// 错误信息。 + public delegate void UpdateVersionListFailureCallback(string downloadUri, string errorMessage); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListFailureCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListFailureCallback.cs.meta new file mode 100644 index 0000000..0f08aba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListFailureCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df6ea73c9ca77ea4b8fc195998d48a80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListSuccessCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListSuccessCallback.cs new file mode 100644 index 0000000..01cc3ff --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListSuccessCallback.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 版本资源列表更新成功回调函数。 + /// + /// 版本资源列表更新后存放路径。 + /// 版本资源列表更新地址。 + public delegate void UpdateVersionListSuccessCallback(string downloadPath, string downloadUri); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListSuccessCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListSuccessCallback.cs.meta new file mode 100644 index 0000000..12a5a50 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/UpdateVersionListSuccessCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f8be8c99f5a36d74187802bd68a8cbdd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/VerifyResourcesCompleteCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/VerifyResourcesCompleteCallback.cs new file mode 100644 index 0000000..0202418 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/VerifyResourcesCompleteCallback.cs @@ -0,0 +1,15 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Resource +{ + /// + /// 使用可更新模式并校验资源完成时的回调函数。 + /// + /// 校验资源结果,全部成功为 true,否则为 false。 + public delegate void VerifyResourcesCompleteCallback(bool result); +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/VerifyResourcesCompleteCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/VerifyResourcesCompleteCallback.cs.meta new file mode 100644 index 0000000..8ff6e96 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Resource/VerifyResourcesCompleteCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec29233d2ef58ab48aa77876f80c796e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene.meta new file mode 100644 index 0000000..ac8d678 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 40791dd36b5332a4f85177695931ab59 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/ISceneManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/ISceneManager.cs new file mode 100644 index 0000000..554700d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/ISceneManager.cs @@ -0,0 +1,160 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.Scene +{ + /// + /// 场景管理器接口。 + /// + public interface ISceneManager + { + /// + /// 加载场景成功事件。 + /// + event EventHandler LoadSceneSuccess; + + /// + /// 加载场景失败事件。 + /// + event EventHandler LoadSceneFailure; + + /// + /// 加载场景更新事件。 + /// + event EventHandler LoadSceneUpdate; + + /// + /// 加载场景时加载依赖资源事件。 + /// + event EventHandler LoadSceneDependencyAsset; + + /// + /// 卸载场景成功事件。 + /// + event EventHandler UnloadSceneSuccess; + + /// + /// 卸载场景失败事件。 + /// + event EventHandler UnloadSceneFailure; + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + void SetResourceManager(IResourceManager resourceManager); + + /// + /// 获取场景是否已加载。 + /// + /// 场景资源名称。 + /// 场景是否已加载。 + bool SceneIsLoaded(string sceneAssetName); + + /// + /// 获取已加载场景的资源名称。 + /// + /// 已加载场景的资源名称。 + string[] GetLoadedSceneAssetNames(); + + /// + /// 获取已加载场景的资源名称。 + /// + /// 已加载场景的资源名称。 + void GetLoadedSceneAssetNames(List results); + + /// + /// 获取场景是否正在加载。 + /// + /// 场景资源名称。 + /// 场景是否正在加载。 + bool SceneIsLoading(string sceneAssetName); + + /// + /// 获取正在加载场景的资源名称。 + /// + /// 正在加载场景的资源名称。 + string[] GetLoadingSceneAssetNames(); + + /// + /// 获取正在加载场景的资源名称。 + /// + /// 正在加载场景的资源名称。 + void GetLoadingSceneAssetNames(List results); + + /// + /// 获取场景是否正在卸载。 + /// + /// 场景资源名称。 + /// 场景是否正在卸载。 + bool SceneIsUnloading(string sceneAssetName); + + /// + /// 获取正在卸载场景的资源名称。 + /// + /// 正在卸载场景的资源名称。 + string[] GetUnloadingSceneAssetNames(); + + /// + /// 获取正在卸载场景的资源名称。 + /// + /// 正在卸载场景的资源名称。 + void GetUnloadingSceneAssetNames(List results); + + /// + /// 检查场景资源是否存在。 + /// + /// 要检查场景资源的名称。 + /// 场景资源是否存在。 + bool HasScene(string sceneAssetName); + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + void LoadScene(string sceneAssetName); + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 加载场景资源的优先级。 + void LoadScene(string sceneAssetName, int priority); + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 用户自定义数据。 + void LoadScene(string sceneAssetName, object userData); + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 加载场景资源的优先级。 + /// 用户自定义数据。 + void LoadScene(string sceneAssetName, int priority, object userData); + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + void UnloadScene(string sceneAssetName); + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + /// 用户自定义数据。 + void UnloadScene(string sceneAssetName, object userData); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/ISceneManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/ISceneManager.cs.meta new file mode 100644 index 0000000..580c419 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/ISceneManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba232f82a07ad3f458b23261a83754a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs new file mode 100644 index 0000000..9c85df6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Scene +{ + /// + /// 加载场景时加载依赖资源事件。 + /// + public sealed class LoadSceneDependencyAssetEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载场景时加载依赖资源事件的新实例。 + /// + public LoadSceneDependencyAssetEventArgs() + { + SceneAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建场景时加载依赖资源事件。 + /// + /// 场景资源名称。 + /// 被加载的依赖资源名称。 + /// 当前已加载依赖资源数量。 + /// 总共加载依赖资源数量。 + /// 用户自定义数据。 + /// 创建的场景时加载依赖资源事件。 + public static LoadSceneDependencyAssetEventArgs Create(string sceneAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + LoadSceneDependencyAssetEventArgs loadSceneDependencyAssetEventArgs = ReferencePool.Acquire(); + loadSceneDependencyAssetEventArgs.SceneAssetName = sceneAssetName; + loadSceneDependencyAssetEventArgs.DependencyAssetName = dependencyAssetName; + loadSceneDependencyAssetEventArgs.LoadedCount = loadedCount; + loadSceneDependencyAssetEventArgs.TotalCount = totalCount; + loadSceneDependencyAssetEventArgs.UserData = userData; + return loadSceneDependencyAssetEventArgs; + } + + /// + /// 清理场景时加载依赖资源事件。 + /// + public override void Clear() + { + SceneAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..b6b95c3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 684badaad7df8924d9b6919bf424579d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneFailureEventArgs.cs new file mode 100644 index 0000000..ef4d47d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneFailureEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Scene +{ + /// + /// 加载场景失败事件。 + /// + public sealed class LoadSceneFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载场景失败事件的新实例。 + /// + public LoadSceneFailureEventArgs() + { + SceneAssetName = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载场景失败事件。 + /// + /// 场景资源名称。 + /// 错误信息。 + /// 用户自定义数据。 + /// 创建的加载场景失败事件。 + public static LoadSceneFailureEventArgs Create(string sceneAssetName, string errorMessage, object userData) + { + LoadSceneFailureEventArgs loadSceneFailureEventArgs = ReferencePool.Acquire(); + loadSceneFailureEventArgs.SceneAssetName = sceneAssetName; + loadSceneFailureEventArgs.ErrorMessage = errorMessage; + loadSceneFailureEventArgs.UserData = userData; + return loadSceneFailureEventArgs; + } + + /// + /// 清理加载场景失败事件。 + /// + public override void Clear() + { + SceneAssetName = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneFailureEventArgs.cs.meta new file mode 100644 index 0000000..bb31494 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 649d2a673e06db3459b8a2430730e16b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneSuccessEventArgs.cs new file mode 100644 index 0000000..497ba78 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneSuccessEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Scene +{ + /// + /// 加载场景成功事件。 + /// + public sealed class LoadSceneSuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载场景成功事件的新实例。 + /// + public LoadSceneSuccessEventArgs() + { + SceneAssetName = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载场景成功事件。 + /// + /// 场景资源名称。 + /// 加载持续时间。 + /// 用户自定义数据。 + /// 创建的加载场景成功事件。 + public static LoadSceneSuccessEventArgs Create(string sceneAssetName, float duration, object userData) + { + LoadSceneSuccessEventArgs loadSceneSuccessEventArgs = ReferencePool.Acquire(); + loadSceneSuccessEventArgs.SceneAssetName = sceneAssetName; + loadSceneSuccessEventArgs.Duration = duration; + loadSceneSuccessEventArgs.UserData = userData; + return loadSceneSuccessEventArgs; + } + + /// + /// 清理加载场景成功事件。 + /// + public override void Clear() + { + SceneAssetName = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneSuccessEventArgs.cs.meta new file mode 100644 index 0000000..5ae3cac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aca459d7d59851d41a55eb2b289ce025 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneUpdateEventArgs.cs new file mode 100644 index 0000000..d98e11b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneUpdateEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Scene +{ + /// + /// 加载场景更新事件。 + /// + public sealed class LoadSceneUpdateEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化加载场景更新事件的新实例。 + /// + public LoadSceneUpdateEventArgs() + { + SceneAssetName = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取加载场景进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载场景更新事件。 + /// + /// 场景资源名称。 + /// 加载场景进度。 + /// 用户自定义数据。 + /// 创建的加载场景更新事件。 + public static LoadSceneUpdateEventArgs Create(string sceneAssetName, float progress, object userData) + { + LoadSceneUpdateEventArgs loadSceneUpdateEventArgs = ReferencePool.Acquire(); + loadSceneUpdateEventArgs.SceneAssetName = sceneAssetName; + loadSceneUpdateEventArgs.Progress = progress; + loadSceneUpdateEventArgs.UserData = userData; + return loadSceneUpdateEventArgs; + } + + /// + /// 清理加载场景更新事件。 + /// + public override void Clear() + { + SceneAssetName = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneUpdateEventArgs.cs.meta new file mode 100644 index 0000000..fc6b7be --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/LoadSceneUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ee84ce1eb99bf840b5c011bb848319a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/SceneManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/SceneManager.cs new file mode 100644 index 0000000..7ae7feb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/SceneManager.cs @@ -0,0 +1,508 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.Scene +{ + /// + /// 场景管理器。 + /// + internal sealed class SceneManager : GameFrameworkModule, ISceneManager + { + private readonly List m_LoadedSceneAssetNames; + private readonly List m_LoadingSceneAssetNames; + private readonly List m_UnloadingSceneAssetNames; + private readonly LoadSceneCallbacks m_LoadSceneCallbacks; + private readonly UnloadSceneCallbacks m_UnloadSceneCallbacks; + private IResourceManager m_ResourceManager; + private EventHandler m_LoadSceneSuccessEventHandler; + private EventHandler m_LoadSceneFailureEventHandler; + private EventHandler m_LoadSceneUpdateEventHandler; + private EventHandler m_LoadSceneDependencyAssetEventHandler; + private EventHandler m_UnloadSceneSuccessEventHandler; + private EventHandler m_UnloadSceneFailureEventHandler; + + /// + /// 初始化场景管理器的新实例。 + /// + public SceneManager() + { + m_LoadedSceneAssetNames = new List(); + m_LoadingSceneAssetNames = new List(); + m_UnloadingSceneAssetNames = new List(); + m_LoadSceneCallbacks = new LoadSceneCallbacks(LoadSceneSuccessCallback, LoadSceneFailureCallback, LoadSceneUpdateCallback, LoadSceneDependencyAssetCallback); + m_UnloadSceneCallbacks = new UnloadSceneCallbacks(UnloadSceneSuccessCallback, UnloadSceneFailureCallback); + m_ResourceManager = null; + m_LoadSceneSuccessEventHandler = null; + m_LoadSceneFailureEventHandler = null; + m_LoadSceneUpdateEventHandler = null; + m_LoadSceneDependencyAssetEventHandler = null; + m_UnloadSceneSuccessEventHandler = null; + m_UnloadSceneFailureEventHandler = null; + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal override int Priority + { + get + { + return 2; + } + } + + /// + /// 加载场景成功事件。 + /// + public event EventHandler LoadSceneSuccess + { + add + { + m_LoadSceneSuccessEventHandler += value; + } + remove + { + m_LoadSceneSuccessEventHandler -= value; + } + } + + /// + /// 加载场景失败事件。 + /// + public event EventHandler LoadSceneFailure + { + add + { + m_LoadSceneFailureEventHandler += value; + } + remove + { + m_LoadSceneFailureEventHandler -= value; + } + } + + /// + /// 加载场景更新事件。 + /// + public event EventHandler LoadSceneUpdate + { + add + { + m_LoadSceneUpdateEventHandler += value; + } + remove + { + m_LoadSceneUpdateEventHandler -= value; + } + } + + /// + /// 加载场景时加载依赖资源事件。 + /// + public event EventHandler LoadSceneDependencyAsset + { + add + { + m_LoadSceneDependencyAssetEventHandler += value; + } + remove + { + m_LoadSceneDependencyAssetEventHandler -= value; + } + } + + /// + /// 卸载场景成功事件。 + /// + public event EventHandler UnloadSceneSuccess + { + add + { + m_UnloadSceneSuccessEventHandler += value; + } + remove + { + m_UnloadSceneSuccessEventHandler -= value; + } + } + + /// + /// 卸载场景失败事件。 + /// + public event EventHandler UnloadSceneFailure + { + add + { + m_UnloadSceneFailureEventHandler += value; + } + remove + { + m_UnloadSceneFailureEventHandler -= value; + } + } + + /// + /// 场景管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理场景管理器。 + /// + internal override void Shutdown() + { + string[] loadedSceneAssetNames = m_LoadedSceneAssetNames.ToArray(); + foreach (string loadedSceneAssetName in loadedSceneAssetNames) + { + if (SceneIsUnloading(loadedSceneAssetName)) + { + continue; + } + + UnloadScene(loadedSceneAssetName); + } + + m_LoadedSceneAssetNames.Clear(); + m_LoadingSceneAssetNames.Clear(); + m_UnloadingSceneAssetNames.Clear(); + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + public void SetResourceManager(IResourceManager resourceManager) + { + if (resourceManager == null) + { + throw new GameFrameworkException("Resource manager is invalid."); + } + + m_ResourceManager = resourceManager; + } + + /// + /// 获取场景是否已加载。 + /// + /// 场景资源名称。 + /// 场景是否已加载。 + public bool SceneIsLoaded(string sceneAssetName) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + return m_LoadedSceneAssetNames.Contains(sceneAssetName); + } + + /// + /// 获取已加载场景的资源名称。 + /// + /// 已加载场景的资源名称。 + public string[] GetLoadedSceneAssetNames() + { + return m_LoadedSceneAssetNames.ToArray(); + } + + /// + /// 获取已加载场景的资源名称。 + /// + /// 已加载场景的资源名称。 + public void GetLoadedSceneAssetNames(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + results.AddRange(m_LoadedSceneAssetNames); + } + + /// + /// 获取场景是否正在加载。 + /// + /// 场景资源名称。 + /// 场景是否正在加载。 + public bool SceneIsLoading(string sceneAssetName) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + return m_LoadingSceneAssetNames.Contains(sceneAssetName); + } + + /// + /// 获取正在加载场景的资源名称。 + /// + /// 正在加载场景的资源名称。 + public string[] GetLoadingSceneAssetNames() + { + return m_LoadingSceneAssetNames.ToArray(); + } + + /// + /// 获取正在加载场景的资源名称。 + /// + /// 正在加载场景的资源名称。 + public void GetLoadingSceneAssetNames(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + results.AddRange(m_LoadingSceneAssetNames); + } + + /// + /// 获取场景是否正在卸载。 + /// + /// 场景资源名称。 + /// 场景是否正在卸载。 + public bool SceneIsUnloading(string sceneAssetName) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + return m_UnloadingSceneAssetNames.Contains(sceneAssetName); + } + + /// + /// 获取正在卸载场景的资源名称。 + /// + /// 正在卸载场景的资源名称。 + public string[] GetUnloadingSceneAssetNames() + { + return m_UnloadingSceneAssetNames.ToArray(); + } + + /// + /// 获取正在卸载场景的资源名称。 + /// + /// 正在卸载场景的资源名称。 + public void GetUnloadingSceneAssetNames(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + results.AddRange(m_UnloadingSceneAssetNames); + } + + /// + /// 检查场景资源是否存在。 + /// + /// 要检查场景资源的名称。 + /// 场景资源是否存在。 + public bool HasScene(string sceneAssetName) + { + return m_ResourceManager.HasAsset(sceneAssetName) != HasAssetResult.NotExist; + } + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + public void LoadScene(string sceneAssetName) + { + LoadScene(sceneAssetName, Constant.DefaultPriority, null); + } + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 加载场景资源的优先级。 + public void LoadScene(string sceneAssetName, int priority) + { + LoadScene(sceneAssetName, priority, null); + } + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, object userData) + { + LoadScene(sceneAssetName, Constant.DefaultPriority, userData); + } + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 加载场景资源的优先级。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, int priority, object userData) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + if (m_ResourceManager == null) + { + throw new GameFrameworkException("You must set resource manager first."); + } + + if (SceneIsUnloading(sceneAssetName)) + { + throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is being unloaded.", sceneAssetName)); + } + + if (SceneIsLoading(sceneAssetName)) + { + throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is being loaded.", sceneAssetName)); + } + + if (SceneIsLoaded(sceneAssetName)) + { + throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is already loaded.", sceneAssetName)); + } + + m_LoadingSceneAssetNames.Add(sceneAssetName); + m_ResourceManager.LoadScene(sceneAssetName, priority, m_LoadSceneCallbacks, userData); + } + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + public void UnloadScene(string sceneAssetName) + { + UnloadScene(sceneAssetName, null); + } + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + /// 用户自定义数据。 + public void UnloadScene(string sceneAssetName, object userData) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + throw new GameFrameworkException("Scene asset name is invalid."); + } + + if (m_ResourceManager == null) + { + throw new GameFrameworkException("You must set resource manager first."); + } + + if (SceneIsUnloading(sceneAssetName)) + { + throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is being unloaded.", sceneAssetName)); + } + + if (SceneIsLoading(sceneAssetName)) + { + throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is being loaded.", sceneAssetName)); + } + + if (!SceneIsLoaded(sceneAssetName)) + { + throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is not loaded yet.", sceneAssetName)); + } + + m_UnloadingSceneAssetNames.Add(sceneAssetName); + m_ResourceManager.UnloadScene(sceneAssetName, m_UnloadSceneCallbacks, userData); + } + + private void LoadSceneSuccessCallback(string sceneAssetName, float duration, object userData) + { + m_LoadingSceneAssetNames.Remove(sceneAssetName); + m_LoadedSceneAssetNames.Add(sceneAssetName); + if (m_LoadSceneSuccessEventHandler != null) + { + LoadSceneSuccessEventArgs loadSceneSuccessEventArgs = LoadSceneSuccessEventArgs.Create(sceneAssetName, duration, userData); + m_LoadSceneSuccessEventHandler(this, loadSceneSuccessEventArgs); + ReferencePool.Release(loadSceneSuccessEventArgs); + } + } + + private void LoadSceneFailureCallback(string sceneAssetName, LoadResourceStatus status, string errorMessage, object userData) + { + m_LoadingSceneAssetNames.Remove(sceneAssetName); + string appendErrorMessage = Utility.Text.Format("Load scene failure, scene asset name '{0}', status '{1}', error message '{2}'.", sceneAssetName, status, errorMessage); + if (m_LoadSceneFailureEventHandler != null) + { + LoadSceneFailureEventArgs loadSceneFailureEventArgs = LoadSceneFailureEventArgs.Create(sceneAssetName, appendErrorMessage, userData); + m_LoadSceneFailureEventHandler(this, loadSceneFailureEventArgs); + ReferencePool.Release(loadSceneFailureEventArgs); + return; + } + + throw new GameFrameworkException(appendErrorMessage); + } + + private void LoadSceneUpdateCallback(string sceneAssetName, float progress, object userData) + { + if (m_LoadSceneUpdateEventHandler != null) + { + LoadSceneUpdateEventArgs loadSceneUpdateEventArgs = LoadSceneUpdateEventArgs.Create(sceneAssetName, progress, userData); + m_LoadSceneUpdateEventHandler(this, loadSceneUpdateEventArgs); + ReferencePool.Release(loadSceneUpdateEventArgs); + } + } + + private void LoadSceneDependencyAssetCallback(string sceneAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + if (m_LoadSceneDependencyAssetEventHandler != null) + { + LoadSceneDependencyAssetEventArgs loadSceneDependencyAssetEventArgs = LoadSceneDependencyAssetEventArgs.Create(sceneAssetName, dependencyAssetName, loadedCount, totalCount, userData); + m_LoadSceneDependencyAssetEventHandler(this, loadSceneDependencyAssetEventArgs); + ReferencePool.Release(loadSceneDependencyAssetEventArgs); + } + } + + private void UnloadSceneSuccessCallback(string sceneAssetName, object userData) + { + m_UnloadingSceneAssetNames.Remove(sceneAssetName); + m_LoadedSceneAssetNames.Remove(sceneAssetName); + if (m_UnloadSceneSuccessEventHandler != null) + { + UnloadSceneSuccessEventArgs unloadSceneSuccessEventArgs = UnloadSceneSuccessEventArgs.Create(sceneAssetName, userData); + m_UnloadSceneSuccessEventHandler(this, unloadSceneSuccessEventArgs); + ReferencePool.Release(unloadSceneSuccessEventArgs); + } + } + + private void UnloadSceneFailureCallback(string sceneAssetName, object userData) + { + m_UnloadingSceneAssetNames.Remove(sceneAssetName); + if (m_UnloadSceneFailureEventHandler != null) + { + UnloadSceneFailureEventArgs unloadSceneFailureEventArgs = UnloadSceneFailureEventArgs.Create(sceneAssetName, userData); + m_UnloadSceneFailureEventHandler(this, unloadSceneFailureEventArgs); + ReferencePool.Release(unloadSceneFailureEventArgs); + return; + } + + throw new GameFrameworkException(Utility.Text.Format("Unload scene failure, scene asset name '{0}'.", sceneAssetName)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/SceneManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/SceneManager.cs.meta new file mode 100644 index 0000000..5af88f9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/SceneManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9beaade359bbaac499c456248ad86133 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneFailureEventArgs.cs new file mode 100644 index 0000000..9d39a93 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneFailureEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Scene +{ + /// + /// 卸载场景失败事件。 + /// + public sealed class UnloadSceneFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化卸载场景失败事件的新实例。 + /// + public UnloadSceneFailureEventArgs() + { + SceneAssetName = null; + UserData = null; + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建卸载场景失败事件。 + /// + /// 场景资源名称。 + /// 用户自定义数据。 + /// 创建的卸载场景失败事件。 + public static UnloadSceneFailureEventArgs Create(string sceneAssetName, object userData) + { + UnloadSceneFailureEventArgs unloadSceneFailureEventArgs = ReferencePool.Acquire(); + unloadSceneFailureEventArgs.SceneAssetName = sceneAssetName; + unloadSceneFailureEventArgs.UserData = userData; + return unloadSceneFailureEventArgs; + } + + /// + /// 清理卸载场景失败事件。 + /// + public override void Clear() + { + SceneAssetName = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneFailureEventArgs.cs.meta new file mode 100644 index 0000000..3098ae5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf3ddc418ace15e4687690c54ddfaaf5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneSuccessEventArgs.cs new file mode 100644 index 0000000..99b5611 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneSuccessEventArgs.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Scene +{ + /// + /// 卸载场景成功事件。 + /// + public sealed class UnloadSceneSuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化卸载场景成功事件的新实例。 + /// + public UnloadSceneSuccessEventArgs() + { + SceneAssetName = null; + UserData = null; + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建卸载场景成功事件。 + /// + /// 场景资源名称。 + /// 用户自定义数据。 + /// 创建的卸载场景成功事件。 + public static UnloadSceneSuccessEventArgs Create(string sceneAssetName, object userData) + { + UnloadSceneSuccessEventArgs unloadSceneSuccessEventArgs = ReferencePool.Acquire(); + unloadSceneSuccessEventArgs.SceneAssetName = sceneAssetName; + unloadSceneSuccessEventArgs.UserData = userData; + return unloadSceneSuccessEventArgs; + } + + /// + /// 清理卸载场景成功事件。 + /// + public override void Clear() + { + SceneAssetName = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneSuccessEventArgs.cs.meta new file mode 100644 index 0000000..1786d47 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Scene/UnloadSceneSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3d29ec2157d3ca428b45a29b378fb71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting.meta new file mode 100644 index 0000000..546ae28 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 119808378a10f044590fe3ee8ab7ac63 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingHelper.cs new file mode 100644 index 0000000..86777cf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingHelper.cs @@ -0,0 +1,206 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Setting +{ + /// + /// 游戏配置辅助器接口。 + /// + public interface ISettingHelper + { + /// + /// 获取游戏配置项数量。 + /// + int Count + { + get; + } + + /// + /// 加载游戏配置。 + /// + /// 是否加载游戏配置成功。 + bool Load(); + + /// + /// 保存游戏配置。 + /// + /// 是否保存游戏配置成功。 + bool Save(); + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + string[] GetAllSettingNames(); + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + void GetAllSettingNames(List results); + + /// + /// 检查是否存在指定游戏配置项。 + /// + /// 要检查游戏配置项的名称。 + /// 指定的游戏配置项是否存在。 + bool HasSetting(string settingName); + + /// + /// 移除指定游戏配置项。 + /// + /// 要移除游戏配置项的名称。 + /// 是否移除指定游戏配置项成功。 + bool RemoveSetting(string settingName); + + /// + /// 清空所有游戏配置项。 + /// + void RemoveAllSettings(); + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的布尔值。 + bool GetBool(string settingName); + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + bool GetBool(string settingName, bool defaultValue); + + /// + /// 向指定游戏配置项写入布尔值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的布尔值。 + void SetBool(string settingName, bool value); + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的整数值。 + int GetInt(string settingName); + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的整数值。 + int GetInt(string settingName, int defaultValue); + + /// + /// 向指定游戏配置项写入整数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的整数值。 + void SetInt(string settingName, int value); + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的浮点数值。 + float GetFloat(string settingName); + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + float GetFloat(string settingName, float defaultValue); + + /// + /// 向指定游戏配置项写入浮点数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的浮点数值。 + void SetFloat(string settingName, float value); + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的字符串值。 + string GetString(string settingName); + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + string GetString(string settingName, string defaultValue); + + /// + /// 向指定游戏配置项写入字符串值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的字符串值。 + void SetString(string settingName, string value); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + T GetObject(string settingName); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + object GetObject(Type objectType, string settingName); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + T GetObject(string settingName, T defaultObj); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + object GetObject(Type objectType, string settingName, object defaultObj); + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入对象的类型。 + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + void SetObject(string settingName, T obj); + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + void SetObject(string settingName, object obj); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingHelper.cs.meta new file mode 100644 index 0000000..5a95624 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd6a8c650ab78ad4fbfab9f888d07ee5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingManager.cs new file mode 100644 index 0000000..d0dccbe --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingManager.cs @@ -0,0 +1,212 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Setting +{ + /// + /// 游戏配置管理器接口。 + /// + public interface ISettingManager + { + /// + /// 获取游戏配置项数量。 + /// + int Count + { + get; + } + + /// + /// 设置游戏配置辅助器。 + /// + /// 游戏配置辅助器。 + void SetSettingHelper(ISettingHelper settingHelper); + + /// + /// 加载游戏配置。 + /// + /// 是否加载游戏配置成功。 + bool Load(); + + /// + /// 保存游戏配置。 + /// + /// 是否保存游戏配置成功。 + bool Save(); + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + string[] GetAllSettingNames(); + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + void GetAllSettingNames(List results); + + /// + /// 检查是否存在指定游戏配置项。 + /// + /// 要检查游戏配置项的名称。 + /// 指定的游戏配置项是否存在。 + bool HasSetting(string settingName); + + /// + /// 移除指定游戏配置项。 + /// + /// 要移除游戏配置项的名称。 + /// 是否移除指定游戏配置项成功。 + bool RemoveSetting(string settingName); + + /// + /// 清空所有游戏配置项。 + /// + void RemoveAllSettings(); + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的布尔值。 + bool GetBool(string settingName); + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + bool GetBool(string settingName, bool defaultValue); + + /// + /// 向指定游戏配置项写入布尔值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的布尔值。 + void SetBool(string settingName, bool value); + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的整数值。 + int GetInt(string settingName); + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的整数值。 + int GetInt(string settingName, int defaultValue); + + /// + /// 向指定游戏配置项写入整数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的整数值。 + void SetInt(string settingName, int value); + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的浮点数值。 + float GetFloat(string settingName); + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + float GetFloat(string settingName, float defaultValue); + + /// + /// 向指定游戏配置项写入浮点数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的浮点数值。 + void SetFloat(string settingName, float value); + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的字符串值。 + string GetString(string settingName); + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + string GetString(string settingName, string defaultValue); + + /// + /// 向指定游戏配置项写入字符串值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的字符串值。 + void SetString(string settingName, string value); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + T GetObject(string settingName); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + object GetObject(Type objectType, string settingName); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + T GetObject(string settingName, T defaultObj); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + object GetObject(Type objectType, string settingName, object defaultObj); + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入对象的类型。 + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + void SetObject(string settingName, T obj); + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + void SetObject(string settingName, object obj); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingManager.cs.meta new file mode 100644 index 0000000..b0135f4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/ISettingManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2fd340e8af449e44c851d7336931989b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/SettingManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/SettingManager.cs new file mode 100644 index 0000000..b2373c3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/SettingManager.cs @@ -0,0 +1,565 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.Setting +{ + /// + /// 游戏配置管理器。 + /// + internal sealed class SettingManager : GameFrameworkModule, ISettingManager + { + private ISettingHelper m_SettingHelper; + + /// + /// 初始化游戏配置管理器的新实例。 + /// + public SettingManager() + { + m_SettingHelper = null; + } + + /// + /// 获取游戏配置项数量。 + /// + public int Count + { + get + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + return m_SettingHelper.Count; + } + } + + /// + /// 游戏配置管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理游戏配置管理器。 + /// + internal override void Shutdown() + { + Save(); + } + + /// + /// 设置游戏配置辅助器。 + /// + /// 游戏配置辅助器。 + public void SetSettingHelper(ISettingHelper settingHelper) + { + if (settingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + m_SettingHelper = settingHelper; + } + + /// + /// 加载游戏配置。 + /// + /// 是否加载游戏配置成功。 + public bool Load() + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + return m_SettingHelper.Load(); + } + + /// + /// 保存游戏配置。 + /// + /// 是否保存游戏配置成功。 + public bool Save() + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + return m_SettingHelper.Save(); + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public string[] GetAllSettingNames() + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + return m_SettingHelper.GetAllSettingNames(); + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public void GetAllSettingNames(List results) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + m_SettingHelper.GetAllSettingNames(results); + } + + /// + /// 检查是否存在指定游戏配置项。 + /// + /// 要检查游戏配置项的名称。 + /// 指定的游戏配置项是否存在。 + public bool HasSetting(string settingName) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.HasSetting(settingName); + } + + /// + /// 移除指定游戏配置项。 + /// + /// 要移除游戏配置项的名称。 + /// 是否移除指定游戏配置项成功。 + public bool RemoveSetting(string settingName) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.RemoveSetting(settingName); + } + + /// + /// 清空所有游戏配置项。 + /// + public void RemoveAllSettings() + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + m_SettingHelper.RemoveAllSettings(); + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的布尔值。 + public bool GetBool(string settingName) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetBool(settingName); + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + public bool GetBool(string settingName, bool defaultValue) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetBool(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入布尔值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的布尔值。 + public void SetBool(string settingName, bool value) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + m_SettingHelper.SetBool(settingName, value); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的整数值。 + public int GetInt(string settingName) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetInt(settingName); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的整数值。 + public int GetInt(string settingName, int defaultValue) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetInt(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入整数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的整数值。 + public void SetInt(string settingName, int value) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + m_SettingHelper.SetInt(settingName, value); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的浮点数值。 + public float GetFloat(string settingName) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetFloat(settingName); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + public float GetFloat(string settingName, float defaultValue) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetFloat(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入浮点数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的浮点数值。 + public void SetFloat(string settingName, float value) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + m_SettingHelper.SetFloat(settingName, value); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的字符串值。 + public string GetString(string settingName) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetString(settingName); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + public string GetString(string settingName, string defaultValue) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetString(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入字符串值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的字符串值。 + public void SetString(string settingName, string value) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + m_SettingHelper.SetString(settingName, value); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public T GetObject(string settingName) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetObject(settingName); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public object GetObject(Type objectType, string settingName) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetObject(objectType, settingName); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public T GetObject(string settingName, T defaultObj) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetObject(settingName, defaultObj); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public object GetObject(Type objectType, string settingName, object defaultObj) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + return m_SettingHelper.GetObject(objectType, settingName, defaultObj); + } + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入对象的类型。 + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public void SetObject(string settingName, T obj) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + m_SettingHelper.SetObject(settingName, obj); + } + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public void SetObject(string settingName, object obj) + { + if (m_SettingHelper == null) + { + throw new GameFrameworkException("Setting helper is invalid."); + } + + if (string.IsNullOrEmpty(settingName)) + { + throw new GameFrameworkException("Setting name is invalid."); + } + + m_SettingHelper.SetObject(settingName, obj); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/SettingManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/SettingManager.cs.meta new file mode 100644 index 0000000..4392726 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Setting/SettingManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2a2ed92ad2214a46970b139fac12534 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound.meta new file mode 100644 index 0000000..0072539 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c6cd89b7b0099e049825ee853b4bf7e8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/Constant.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/Constant.cs new file mode 100644 index 0000000..3171243 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/Constant.cs @@ -0,0 +1,28 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 声音相关常量。 + /// + internal static class Constant + { + internal const float DefaultTime = 0f; + internal const bool DefaultMute = false; + internal const bool DefaultLoop = false; + internal const int DefaultPriority = 0; + internal const float DefaultVolume = 1f; + internal const float DefaultFadeInSeconds = 0f; + internal const float DefaultFadeOutSeconds = 0f; + internal const float DefaultPitch = 1f; + internal const float DefaultPanStereo = 0f; + internal const float DefaultSpatialBlend = 0f; + internal const float DefaultMaxDistance = 100f; + internal const float DefaultDopplerLevel = 1f; + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/Constant.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/Constant.cs.meta new file mode 100644 index 0000000..d285e4c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/Constant.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73ec2070ae8732540a594a399690a510 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgent.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgent.cs new file mode 100644 index 0000000..2c39c75 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgent.cs @@ -0,0 +1,210 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 声音代理接口。 + /// + public interface ISoundAgent + { + /// + /// 获取所在的声音组。 + /// + ISoundGroup SoundGroup + { + get; + } + + /// + /// 获取声音的序列编号。 + /// + int SerialId + { + get; + } + + /// + /// 获取当前是否正在播放。 + /// + bool IsPlaying + { + get; + } + + /// + /// 获取声音长度。 + /// + float Length + { + get; + } + + /// + /// 获取或设置播放位置。 + /// + float Time + { + get; + set; + } + + /// + /// 获取或设置是否静音。 + /// + bool Mute + { + get; + } + + /// + /// 获取或设置在声音组内是否静音。 + /// + bool MuteInSoundGroup + { + get; + set; + } + + /// + /// 获取或设置是否循环播放。 + /// + bool Loop + { + get; + set; + } + + /// + /// 获取或设置声音优先级。 + /// + int Priority + { + get; + set; + } + + /// + /// 获取音量大小。 + /// + float Volume + { + get; + } + + /// + /// 获取或设置在声音组内音量大小。 + /// + float VolumeInSoundGroup + { + get; + set; + } + + /// + /// 获取或设置声音音调。 + /// + float Pitch + { + get; + set; + } + + /// + /// 获取或设置声音立体声声相。 + /// + float PanStereo + { + get; + set; + } + + /// + /// 获取或设置声音空间混合量。 + /// + float SpatialBlend + { + get; + set; + } + + /// + /// 获取或设置声音最大距离。 + /// + float MaxDistance + { + get; + set; + } + + /// + /// 获取或设置声音多普勒等级。 + /// + float DopplerLevel + { + get; + set; + } + + /// + /// 获取声音代理辅助器。 + /// + ISoundAgentHelper Helper + { + get; + } + + /// + /// 播放声音。 + /// + void Play(); + + /// + /// 播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + void Play(float fadeInSeconds); + + /// + /// 停止播放声音。 + /// + void Stop(); + + /// + /// 停止播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + void Stop(float fadeOutSeconds); + + /// + /// 暂停播放声音。 + /// + void Pause(); + + /// + /// 暂停播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + void Pause(float fadeOutSeconds); + + /// + /// 恢复播放声音。 + /// + void Resume(); + + /// + /// 恢复播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + void Resume(float fadeInSeconds); + + /// + /// 重置声音代理。 + /// + void Reset(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgent.cs.meta new file mode 100644 index 0000000..b89c3e2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39b05094e2882604786408581f61a677 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgentHelper.cs new file mode 100644 index 0000000..791e4fc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgentHelper.cs @@ -0,0 +1,164 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.Sound +{ + /// + /// 声音代理辅助器接口。 + /// + public interface ISoundAgentHelper + { + /// + /// 获取当前是否正在播放。 + /// + bool IsPlaying + { + get; + } + + /// + /// 获取声音长度。 + /// + float Length + { + get; + } + + /// + /// 获取或设置播放位置。 + /// + float Time + { + get; + set; + } + + /// + /// 获取或设置是否静音。 + /// + bool Mute + { + get; + set; + } + + /// + /// 获取或设置是否循环播放。 + /// + bool Loop + { + get; + set; + } + + /// + /// 获取或设置声音优先级。 + /// + int Priority + { + get; + set; + } + + /// + /// 获取或设置音量大小。 + /// + float Volume + { + get; + set; + } + + /// + /// 获取或设置声音音调。 + /// + float Pitch + { + get; + set; + } + + /// + /// 获取或设置声音立体声声相。 + /// + float PanStereo + { + get; + set; + } + + /// + /// 获取或设置声音空间混合量。 + /// + float SpatialBlend + { + get; + set; + } + + /// + /// 获取或设置声音最大距离。 + /// + float MaxDistance + { + get; + set; + } + + /// + /// 获取或设置声音多普勒等级。 + /// + float DopplerLevel + { + get; + set; + } + + /// + /// 重置声音代理事件。 + /// + event EventHandler ResetSoundAgent; + + /// + /// 播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + void Play(float fadeInSeconds); + + /// + /// 停止播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + void Stop(float fadeOutSeconds); + + /// + /// 暂停播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + void Pause(float fadeOutSeconds); + + /// + /// 恢复播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + void Resume(float fadeInSeconds); + + /// + /// 重置声音代理辅助器。 + /// + void Reset(); + + /// + /// 设置声音资源。 + /// + /// 声音资源。 + /// 是否设置声音资源成功。 + bool SetSoundAsset(object soundAsset); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgentHelper.cs.meta new file mode 100644 index 0000000..be151e5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a198d2b5273597e4a9e92d64e0b9d87d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroup.cs new file mode 100644 index 0000000..5b10d73 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroup.cs @@ -0,0 +1,77 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 声音组接口。 + /// + public interface ISoundGroup + { + /// + /// 获取声音组名称。 + /// + string Name + { + get; + } + + /// + /// 获取声音代理数。 + /// + int SoundAgentCount + { + get; + } + + /// + /// 获取或设置声音组中的声音是否避免被同优先级声音替换。 + /// + bool AvoidBeingReplacedBySamePriority + { + get; + set; + } + + /// + /// 获取或设置声音组静音。 + /// + bool Mute + { + get; + set; + } + + /// + /// 获取或设置声音组音量。 + /// + float Volume + { + get; + set; + } + + /// + /// 获取声音组辅助器。 + /// + ISoundGroupHelper Helper + { + get; + } + + /// + /// 停止所有已加载的声音。 + /// + void StopAllLoadedSounds(); + + /// + /// 停止所有已加载的声音。 + /// + /// 声音淡出时间,以秒为单位。 + void StopAllLoadedSounds(float fadeOutSeconds); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroup.cs.meta new file mode 100644 index 0000000..d1d46ab --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9f65ec262734184e89412198692aa3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroupHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroupHelper.cs new file mode 100644 index 0000000..a692c0b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroupHelper.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 声音组辅助器接口。 + /// + public interface ISoundGroupHelper + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroupHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroupHelper.cs.meta new file mode 100644 index 0000000..83cfefa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundGroupHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 25b0aadd2f5970b45921cfd849adc2cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundHelper.cs new file mode 100644 index 0000000..49e782f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundHelper.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 声音辅助器接口。 + /// + public interface ISoundHelper + { + /// + /// 释放声音资源。 + /// + /// 要释放的声音资源。 + void ReleaseSoundAsset(object soundAsset); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundHelper.cs.meta new file mode 100644 index 0000000..f463b5d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2ab5df40a839f64fa2ad954160d9bb2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundManager.cs new file mode 100644 index 0000000..0a7a61e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundManager.cs @@ -0,0 +1,263 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.Sound +{ + /// + /// 声音管理器接口。 + /// + public interface ISoundManager + { + /// + /// 获取声音组数量。 + /// + int SoundGroupCount + { + get; + } + + /// + /// 播放声音成功事件。 + /// + event EventHandler PlaySoundSuccess; + + /// + /// 播放声音失败事件。 + /// + event EventHandler PlaySoundFailure; + + /// + /// 播放声音更新事件。 + /// + event EventHandler PlaySoundUpdate; + + /// + /// 播放声音时加载依赖资源事件。 + /// + event EventHandler PlaySoundDependencyAsset; + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + void SetResourceManager(IResourceManager resourceManager); + + /// + /// 设置声音辅助器。 + /// + /// 声音辅助器。 + void SetSoundHelper(ISoundHelper soundHelper); + + /// + /// 是否存在指定声音组。 + /// + /// 声音组名称。 + /// 指定声音组是否存在。 + bool HasSoundGroup(string soundGroupName); + + /// + /// 获取指定声音组。 + /// + /// 声音组名称。 + /// 要获取的声音组。 + ISoundGroup GetSoundGroup(string soundGroupName); + + /// + /// 获取所有声音组。 + /// + /// 所有声音组。 + ISoundGroup[] GetAllSoundGroups(); + + /// + /// 获取所有声音组。 + /// + /// 所有声音组。 + void GetAllSoundGroups(List results); + + /// + /// 增加声音组。 + /// + /// 声音组名称。 + /// 声音组辅助器。 + /// 是否增加声音组成功。 + bool AddSoundGroup(string soundGroupName, ISoundGroupHelper soundGroupHelper); + + /// + /// 增加声音组。 + /// + /// 声音组名称。 + /// 声音组中的声音是否避免被同优先级声音替换。 + /// 声音组是否静音。 + /// 声音组音量。 + /// 声音组辅助器。 + /// 是否增加声音组成功。 + bool AddSoundGroup(string soundGroupName, bool soundGroupAvoidBeingReplacedBySamePriority, bool soundGroupMute, float soundGroupVolume, ISoundGroupHelper soundGroupHelper); + + /// + /// 增加声音代理辅助器。 + /// + /// 声音组名称。 + /// 要增加的声音代理辅助器。 + void AddSoundAgentHelper(string soundGroupName, ISoundAgentHelper soundAgentHelper); + + /// + /// 获取所有正在加载声音的序列编号。 + /// + /// 所有正在加载声音的序列编号。 + int[] GetAllLoadingSoundSerialIds(); + + /// + /// 获取所有正在加载声音的序列编号。 + /// + /// 所有正在加载声音的序列编号。 + void GetAllLoadingSoundSerialIds(List results); + + /// + /// 是否正在加载声音。 + /// + /// 声音序列编号。 + /// 是否正在加载声音。 + bool IsLoadingSound(int serialId); + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 声音的序列编号。 + int PlaySound(string soundAssetName, string soundGroupName); + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 声音的序列编号。 + int PlaySound(string soundAssetName, string soundGroupName, int priority); + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 播放声音参数。 + /// 声音的序列编号。 + int PlaySound(string soundAssetName, string soundGroupName, PlaySoundParams playSoundParams); + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 用户自定义数据。 + /// 声音的序列编号。 + int PlaySound(string soundAssetName, string soundGroupName, object userData); + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 声音的序列编号。 + int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams); + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 用户自定义数据。 + /// 声音的序列编号。 + int PlaySound(string soundAssetName, string soundGroupName, int priority, object userData); + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 播放声音参数。 + /// 用户自定义数据。 + /// 声音的序列编号。 + int PlaySound(string soundAssetName, string soundGroupName, PlaySoundParams playSoundParams, object userData); + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 用户自定义数据。 + /// 声音的序列编号。 + int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams, object userData); + + /// + /// 停止播放声音。 + /// + /// 要停止播放声音的序列编号。 + /// 是否停止播放声音成功。 + bool StopSound(int serialId); + + /// + /// 停止播放声音。 + /// + /// 要停止播放声音的序列编号。 + /// 声音淡出时间,以秒为单位。 + /// 是否停止播放声音成功。 + bool StopSound(int serialId, float fadeOutSeconds); + + /// + /// 停止所有已加载的声音。 + /// + void StopAllLoadedSounds(); + + /// + /// 停止所有已加载的声音。 + /// + /// 声音淡出时间,以秒为单位。 + void StopAllLoadedSounds(float fadeOutSeconds); + + /// + /// 停止所有正在加载的声音。 + /// + void StopAllLoadingSounds(); + + /// + /// 暂停播放声音。 + /// + /// 要暂停播放声音的序列编号。 + void PauseSound(int serialId); + + /// + /// 暂停播放声音。 + /// + /// 要暂停播放声音的序列编号。 + /// 声音淡出时间,以秒为单位。 + void PauseSound(int serialId, float fadeOutSeconds); + + /// + /// 恢复播放声音。 + /// + /// 要恢复播放声音的序列编号。 + void ResumeSound(int serialId); + + /// + /// 恢复播放声音。 + /// + /// 要恢复播放声音的序列编号。 + /// 声音淡入时间,以秒为单位。 + void ResumeSound(int serialId, float fadeInSeconds); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundManager.cs.meta new file mode 100644 index 0000000..6c6059f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ISoundManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2231c752fe8bf74389d7b7e1c2cd72b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs new file mode 100644 index 0000000..c8b50e2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs @@ -0,0 +1,143 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 播放声音时加载依赖资源事件。 + /// + public sealed class PlaySoundDependencyAssetEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化播放声音时加载依赖资源事件的新实例。 + /// + public PlaySoundDependencyAssetEventArgs() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取声音的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取声音资源名称。 + /// + public string SoundAssetName + { + get; + private set; + } + + /// + /// 获取声音组名称。 + /// + public string SoundGroupName + { + get; + private set; + } + + /// + /// 获取播放声音参数。 + /// + public PlaySoundParams PlaySoundParams + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建播放声音时加载依赖资源事件。 + /// + /// 声音的序列编号。 + /// 声音资源名称。 + /// 声音组名称。 + /// 播放声音参数。 + /// 被加载的依赖资源名称。 + /// 当前已加载依赖资源数量。 + /// 总共加载依赖资源数量。 + /// 用户自定义数据。 + /// 创建的播放声音时加载依赖资源事件。 + public static PlaySoundDependencyAssetEventArgs Create(int serialId, string soundAssetName, string soundGroupName, PlaySoundParams playSoundParams, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + PlaySoundDependencyAssetEventArgs playSoundDependencyAssetEventArgs = ReferencePool.Acquire(); + playSoundDependencyAssetEventArgs.SerialId = serialId; + playSoundDependencyAssetEventArgs.SoundAssetName = soundAssetName; + playSoundDependencyAssetEventArgs.SoundGroupName = soundGroupName; + playSoundDependencyAssetEventArgs.PlaySoundParams = playSoundParams; + playSoundDependencyAssetEventArgs.DependencyAssetName = dependencyAssetName; + playSoundDependencyAssetEventArgs.LoadedCount = loadedCount; + playSoundDependencyAssetEventArgs.TotalCount = totalCount; + playSoundDependencyAssetEventArgs.UserData = userData; + return playSoundDependencyAssetEventArgs; + } + + /// + /// 清理播放声音时加载依赖资源事件。 + /// + public override void Clear() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..7456059 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3870242352f33644fa98edaf0f5b714a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundErrorCode.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundErrorCode.cs new file mode 100644 index 0000000..23582fd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundErrorCode.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 播放声音错误码。 + /// + public enum PlaySoundErrorCode : byte + { + /// + /// 未知错误。 + /// + Unknown = 0, + + /// + /// 声音组不存在。 + /// + SoundGroupNotExist, + + /// + /// 声音组没有声音代理。 + /// + SoundGroupHasNoAgent, + + /// + /// 加载资源失败。 + /// + LoadAssetFailure, + + /// + /// 播放声音因优先级低被忽略。 + /// + IgnoredDueToLowPriority, + + /// + /// 设置声音资源失败。 + /// + SetSoundAssetFailure + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundErrorCode.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundErrorCode.cs.meta new file mode 100644 index 0000000..736102c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundErrorCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 506ffd5cce7d287439d2fd7d0e229b7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundFailureEventArgs.cs new file mode 100644 index 0000000..9f33655 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundFailureEventArgs.cs @@ -0,0 +1,130 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 播放声音失败事件。 + /// + public sealed class PlaySoundFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化播放声音失败事件的新实例。 + /// + public PlaySoundFailureEventArgs() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + ErrorCode = PlaySoundErrorCode.Unknown; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取声音的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取声音资源名称。 + /// + public string SoundAssetName + { + get; + private set; + } + + /// + /// 获取声音组名称。 + /// + public string SoundGroupName + { + get; + private set; + } + + /// + /// 获取播放声音参数。 + /// + public PlaySoundParams PlaySoundParams + { + get; + private set; + } + + /// + /// 获取错误码。 + /// + public PlaySoundErrorCode ErrorCode + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建播放声音失败事件。 + /// + /// 声音的序列编号。 + /// 声音资源名称。 + /// 声音组名称。 + /// 播放声音参数。 + /// 错误码。 + /// 错误信息。 + /// 用户自定义数据。 + /// 创建的播放声音失败事件。 + public static PlaySoundFailureEventArgs Create(int serialId, string soundAssetName, string soundGroupName, PlaySoundParams playSoundParams, PlaySoundErrorCode errorCode, string errorMessage, object userData) + { + PlaySoundFailureEventArgs playSoundFailureEventArgs = ReferencePool.Acquire(); + playSoundFailureEventArgs.SerialId = serialId; + playSoundFailureEventArgs.SoundAssetName = soundAssetName; + playSoundFailureEventArgs.SoundGroupName = soundGroupName; + playSoundFailureEventArgs.PlaySoundParams = playSoundParams; + playSoundFailureEventArgs.ErrorCode = errorCode; + playSoundFailureEventArgs.ErrorMessage = errorMessage; + playSoundFailureEventArgs.UserData = userData; + return playSoundFailureEventArgs; + } + + /// + /// 清理播放声音失败事件。 + /// + public override void Clear() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + ErrorCode = PlaySoundErrorCode.Unknown; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundFailureEventArgs.cs.meta new file mode 100644 index 0000000..93e0c4b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dcc0883ff1d420d4abae1eedd6ae4950 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundParams.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundParams.cs new file mode 100644 index 0000000..925b915 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundParams.cs @@ -0,0 +1,249 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 播放声音参数。 + /// + public sealed class PlaySoundParams : IReference + { + private bool m_Referenced; + private float m_Time; + private bool m_MuteInSoundGroup; + private bool m_Loop; + private int m_Priority; + private float m_VolumeInSoundGroup; + private float m_FadeInSeconds; + private float m_Pitch; + private float m_PanStereo; + private float m_SpatialBlend; + private float m_MaxDistance; + private float m_DopplerLevel; + + /// + /// 初始化播放声音参数的新实例。 + /// + public PlaySoundParams() + { + m_Referenced = false; + m_Time = Constant.DefaultTime; + m_MuteInSoundGroup = Constant.DefaultMute; + m_Loop = Constant.DefaultLoop; + m_Priority = Constant.DefaultPriority; + m_VolumeInSoundGroup = Constant.DefaultVolume; + m_FadeInSeconds = Constant.DefaultFadeInSeconds; + m_Pitch = Constant.DefaultPitch; + m_PanStereo = Constant.DefaultPanStereo; + m_SpatialBlend = Constant.DefaultSpatialBlend; + m_MaxDistance = Constant.DefaultMaxDistance; + m_DopplerLevel = Constant.DefaultDopplerLevel; + } + + /// + /// 获取或设置播放位置。 + /// + public float Time + { + get + { + return m_Time; + } + set + { + m_Time = value; + } + } + + /// + /// 获取或设置在声音组内是否静音。 + /// + public bool MuteInSoundGroup + { + get + { + return m_MuteInSoundGroup; + } + set + { + m_MuteInSoundGroup = value; + } + } + + /// + /// 获取或设置是否循环播放。 + /// + public bool Loop + { + get + { + return m_Loop; + } + set + { + m_Loop = value; + } + } + + /// + /// 获取或设置声音优先级。 + /// + public int Priority + { + get + { + return m_Priority; + } + set + { + m_Priority = value; + } + } + + /// + /// 获取或设置在声音组内音量大小。 + /// + public float VolumeInSoundGroup + { + get + { + return m_VolumeInSoundGroup; + } + set + { + m_VolumeInSoundGroup = value; + } + } + + /// + /// 获取或设置声音淡入时间,以秒为单位。 + /// + public float FadeInSeconds + { + get + { + return m_FadeInSeconds; + } + set + { + m_FadeInSeconds = value; + } + } + + /// + /// 获取或设置声音音调。 + /// + public float Pitch + { + get + { + return m_Pitch; + } + set + { + m_Pitch = value; + } + } + + /// + /// 获取或设置声音立体声声相。 + /// + public float PanStereo + { + get + { + return m_PanStereo; + } + set + { + m_PanStereo = value; + } + } + + /// + /// 获取或设置声音空间混合量。 + /// + public float SpatialBlend + { + get + { + return m_SpatialBlend; + } + set + { + m_SpatialBlend = value; + } + } + + /// + /// 获取或设置声音最大距离。 + /// + public float MaxDistance + { + get + { + return m_MaxDistance; + } + set + { + m_MaxDistance = value; + } + } + + /// + /// 获取或设置声音多普勒等级。 + /// + public float DopplerLevel + { + get + { + return m_DopplerLevel; + } + set + { + m_DopplerLevel = value; + } + } + + internal bool Referenced + { + get + { + return m_Referenced; + } + } + + /// + /// 创建播放声音参数。 + /// + /// 创建的播放声音参数。 + public static PlaySoundParams Create() + { + PlaySoundParams playSoundParams = ReferencePool.Acquire(); + playSoundParams.m_Referenced = true; + return playSoundParams; + } + + /// + /// 清理播放声音参数。 + /// + public void Clear() + { + m_Time = Constant.DefaultTime; + m_MuteInSoundGroup = Constant.DefaultMute; + m_Loop = Constant.DefaultLoop; + m_Priority = Constant.DefaultPriority; + m_VolumeInSoundGroup = Constant.DefaultVolume; + m_FadeInSeconds = Constant.DefaultFadeInSeconds; + m_Pitch = Constant.DefaultPitch; + m_PanStereo = Constant.DefaultPanStereo; + m_SpatialBlend = Constant.DefaultSpatialBlend; + m_MaxDistance = Constant.DefaultMaxDistance; + m_DopplerLevel = Constant.DefaultDopplerLevel; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundParams.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundParams.cs.meta new file mode 100644 index 0000000..c07693e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundParams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f0ab03dd1e65114ca9878d4e43d0c2b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundSuccessEventArgs.cs new file mode 100644 index 0000000..0f45e48 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundSuccessEventArgs.cs @@ -0,0 +1,104 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 播放声音成功事件。 + /// + public sealed class PlaySoundSuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化播放声音成功事件的新实例。 + /// + public PlaySoundSuccessEventArgs() + { + SerialId = 0; + SoundAssetName = null; + SoundAgent = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取声音的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取声音资源名称。 + /// + public string SoundAssetName + { + get; + private set; + } + + /// + /// 获取用于播放的声音代理。 + /// + public ISoundAgent SoundAgent + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建播放声音成功事件。 + /// + /// 声音的序列编号。 + /// 声音资源名称。 + /// 用于播放的声音代理。 + /// 加载持续时间。 + /// 用户自定义数据。 + /// 创建的播放声音成功事件。 + public static PlaySoundSuccessEventArgs Create(int serialId, string soundAssetName, ISoundAgent soundAgent, float duration, object userData) + { + PlaySoundSuccessEventArgs playSoundSuccessEventArgs = ReferencePool.Acquire(); + playSoundSuccessEventArgs.SerialId = serialId; + playSoundSuccessEventArgs.SoundAssetName = soundAssetName; + playSoundSuccessEventArgs.SoundAgent = soundAgent; + playSoundSuccessEventArgs.Duration = duration; + playSoundSuccessEventArgs.UserData = userData; + return playSoundSuccessEventArgs; + } + + /// + /// 清理播放声音成功事件。 + /// + public override void Clear() + { + SerialId = 0; + SoundAssetName = null; + SoundAgent = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundSuccessEventArgs.cs.meta new file mode 100644 index 0000000..e2dd2a1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6ff75b138c7a834883b620337f4af60 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundUpdateEventArgs.cs new file mode 100644 index 0000000..b38d5db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundUpdateEventArgs.cs @@ -0,0 +1,117 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 播放声音更新事件。 + /// + public sealed class PlaySoundUpdateEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化播放声音更新事件的新实例。 + /// + public PlaySoundUpdateEventArgs() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取声音的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取声音资源名称。 + /// + public string SoundAssetName + { + get; + private set; + } + + /// + /// 获取声音组名称。 + /// + public string SoundGroupName + { + get; + private set; + } + + /// + /// 获取播放声音参数。 + /// + public PlaySoundParams PlaySoundParams + { + get; + private set; + } + + /// + /// 获取加载声音进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建播放声音更新事件。 + /// + /// 声音的序列编号。 + /// 声音资源名称。 + /// 声音组名称。 + /// 播放声音参数。 + /// 加载声音进度。 + /// 用户自定义数据。 + /// 创建的播放声音更新事件。 + public static PlaySoundUpdateEventArgs Create(int serialId, string soundAssetName, string soundGroupName, PlaySoundParams playSoundParams, float progress, object userData) + { + PlaySoundUpdateEventArgs playSoundUpdateEventArgs = ReferencePool.Acquire(); + playSoundUpdateEventArgs.SerialId = serialId; + playSoundUpdateEventArgs.SoundAssetName = soundAssetName; + playSoundUpdateEventArgs.SoundGroupName = soundGroupName; + playSoundUpdateEventArgs.PlaySoundParams = playSoundParams; + playSoundUpdateEventArgs.Progress = progress; + playSoundUpdateEventArgs.UserData = userData; + return playSoundUpdateEventArgs; + } + + /// + /// 清理播放声音更新事件。 + /// + public override void Clear() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundUpdateEventArgs.cs.meta new file mode 100644 index 0000000..85c3aac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/PlaySoundUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9e09c20f9c203d44847a59958af6152 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ResetSoundAgentEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ResetSoundAgentEventArgs.cs new file mode 100644 index 0000000..d7149cb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ResetSoundAgentEventArgs.cs @@ -0,0 +1,39 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + /// + /// 重置声音代理事件。 + /// + public sealed class ResetSoundAgentEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化重置声音代理事件的新实例。 + /// + public ResetSoundAgentEventArgs() + { + } + + /// + /// 创建重置声音代理事件。 + /// + /// 创建的重置声音代理事件。 + public static ResetSoundAgentEventArgs Create() + { + ResetSoundAgentEventArgs resetSoundAgentEventArgs = ReferencePool.Acquire(); + return resetSoundAgentEventArgs; + } + + /// + /// 清理重置声音代理事件。 + /// + public override void Clear() + { + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ResetSoundAgentEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ResetSoundAgentEventArgs.cs.meta new file mode 100644 index 0000000..e51c563 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/ResetSoundAgentEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e55f60639c30d114fb45eb41e641fb7c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.PlaySoundInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.PlaySoundInfo.cs new file mode 100644 index 0000000..c5911e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.PlaySoundInfo.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.Sound +{ + internal sealed partial class SoundManager : GameFrameworkModule, ISoundManager + { + private sealed class PlaySoundInfo : IReference + { + private int m_SerialId; + private SoundGroup m_SoundGroup; + private PlaySoundParams m_PlaySoundParams; + private object m_UserData; + + public PlaySoundInfo() + { + m_SerialId = 0; + m_SoundGroup = null; + m_PlaySoundParams = null; + m_UserData = null; + } + + public int SerialId + { + get + { + return m_SerialId; + } + } + + public SoundGroup SoundGroup + { + get + { + return m_SoundGroup; + } + } + + public PlaySoundParams PlaySoundParams + { + get + { + return m_PlaySoundParams; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + + public static PlaySoundInfo Create(int serialId, SoundGroup soundGroup, PlaySoundParams playSoundParams, object userData) + { + PlaySoundInfo playSoundInfo = ReferencePool.Acquire(); + playSoundInfo.m_SerialId = serialId; + playSoundInfo.m_SoundGroup = soundGroup; + playSoundInfo.m_PlaySoundParams = playSoundParams; + playSoundInfo.m_UserData = userData; + return playSoundInfo; + } + + public void Clear() + { + m_SerialId = 0; + m_SoundGroup = null; + m_PlaySoundParams = null; + m_UserData = null; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.PlaySoundInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.PlaySoundInfo.cs.meta new file mode 100644 index 0000000..5576f27 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.PlaySoundInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d507b6824e0ed74d8b71e9c14ba6f09 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundAgent.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundAgent.cs new file mode 100644 index 0000000..33fd630 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundAgent.cs @@ -0,0 +1,421 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.Sound +{ + internal sealed partial class SoundManager : GameFrameworkModule, ISoundManager + { + /// + /// 声音代理。 + /// + private sealed class SoundAgent : ISoundAgent + { + private readonly SoundGroup m_SoundGroup; + private readonly ISoundHelper m_SoundHelper; + private readonly ISoundAgentHelper m_SoundAgentHelper; + private int m_SerialId; + private object m_SoundAsset; + private DateTime m_SetSoundAssetTime; + private bool m_MuteInSoundGroup; + private float m_VolumeInSoundGroup; + + /// + /// 初始化声音代理的新实例。 + /// + /// 所在的声音组。 + /// 声音辅助器接口。 + /// 声音代理辅助器接口。 + public SoundAgent(SoundGroup soundGroup, ISoundHelper soundHelper, ISoundAgentHelper soundAgentHelper) + { + if (soundGroup == null) + { + throw new GameFrameworkException("Sound group is invalid."); + } + + if (soundHelper == null) + { + throw new GameFrameworkException("Sound helper is invalid."); + } + + if (soundAgentHelper == null) + { + throw new GameFrameworkException("Sound agent helper is invalid."); + } + + m_SoundGroup = soundGroup; + m_SoundHelper = soundHelper; + m_SoundAgentHelper = soundAgentHelper; + m_SoundAgentHelper.ResetSoundAgent += OnResetSoundAgent; + m_SerialId = 0; + m_SoundAsset = null; + Reset(); + } + + /// + /// 获取所在的声音组。 + /// + public ISoundGroup SoundGroup + { + get + { + return m_SoundGroup; + } + } + + /// + /// 获取或设置声音的序列编号。 + /// + public int SerialId + { + get + { + return m_SerialId; + } + set + { + m_SerialId = value; + } + } + + /// + /// 获取当前是否正在播放。 + /// + public bool IsPlaying + { + get + { + return m_SoundAgentHelper.IsPlaying; + } + } + + /// + /// 获取声音长度。 + /// + public float Length + { + get + { + return m_SoundAgentHelper.Length; + } + } + + /// + /// 获取或设置播放位置。 + /// + public float Time + { + get + { + return m_SoundAgentHelper.Time; + } + set + { + m_SoundAgentHelper.Time = value; + } + } + + /// + /// 获取是否静音。 + /// + public bool Mute + { + get + { + return m_SoundAgentHelper.Mute; + } + } + + /// + /// 获取或设置在声音组内是否静音。 + /// + public bool MuteInSoundGroup + { + get + { + return m_MuteInSoundGroup; + } + set + { + m_MuteInSoundGroup = value; + RefreshMute(); + } + } + + /// + /// 获取或设置是否循环播放。 + /// + public bool Loop + { + get + { + return m_SoundAgentHelper.Loop; + } + set + { + m_SoundAgentHelper.Loop = value; + } + } + + /// + /// 获取或设置声音优先级。 + /// + public int Priority + { + get + { + return m_SoundAgentHelper.Priority; + } + set + { + m_SoundAgentHelper.Priority = value; + } + } + + /// + /// 获取音量大小。 + /// + public float Volume + { + get + { + return m_SoundAgentHelper.Volume; + } + } + + /// + /// 获取或设置在声音组内音量大小。 + /// + public float VolumeInSoundGroup + { + get + { + return m_VolumeInSoundGroup; + } + set + { + m_VolumeInSoundGroup = value; + RefreshVolume(); + } + } + + /// + /// 获取或设置声音音调。 + /// + public float Pitch + { + get + { + return m_SoundAgentHelper.Pitch; + } + set + { + m_SoundAgentHelper.Pitch = value; + } + } + + /// + /// 获取或设置声音立体声声相。 + /// + public float PanStereo + { + get + { + return m_SoundAgentHelper.PanStereo; + } + set + { + m_SoundAgentHelper.PanStereo = value; + } + } + + /// + /// 获取或设置声音空间混合量。 + /// + public float SpatialBlend + { + get + { + return m_SoundAgentHelper.SpatialBlend; + } + set + { + m_SoundAgentHelper.SpatialBlend = value; + } + } + + /// + /// 获取或设置声音最大距离。 + /// + public float MaxDistance + { + get + { + return m_SoundAgentHelper.MaxDistance; + } + set + { + m_SoundAgentHelper.MaxDistance = value; + } + } + + /// + /// 获取或设置声音多普勒等级。 + /// + public float DopplerLevel + { + get + { + return m_SoundAgentHelper.DopplerLevel; + } + set + { + m_SoundAgentHelper.DopplerLevel = value; + } + } + + /// + /// 获取声音代理辅助器。 + /// + public ISoundAgentHelper Helper + { + get + { + return m_SoundAgentHelper; + } + } + + /// + /// 获取声音创建时间。 + /// + internal DateTime SetSoundAssetTime + { + get + { + return m_SetSoundAssetTime; + } + } + + /// + /// 播放声音。 + /// + public void Play() + { + m_SoundAgentHelper.Play(Constant.DefaultFadeInSeconds); + } + + /// + /// 播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + public void Play(float fadeInSeconds) + { + m_SoundAgentHelper.Play(fadeInSeconds); + } + + /// + /// 停止播放声音。 + /// + public void Stop() + { + m_SoundAgentHelper.Stop(Constant.DefaultFadeOutSeconds); + } + + /// + /// 停止播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + public void Stop(float fadeOutSeconds) + { + m_SoundAgentHelper.Stop(fadeOutSeconds); + } + + /// + /// 暂停播放声音。 + /// + public void Pause() + { + m_SoundAgentHelper.Pause(Constant.DefaultFadeOutSeconds); + } + + /// + /// 暂停播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + public void Pause(float fadeOutSeconds) + { + m_SoundAgentHelper.Pause(fadeOutSeconds); + } + + /// + /// 恢复播放声音。 + /// + public void Resume() + { + m_SoundAgentHelper.Resume(Constant.DefaultFadeInSeconds); + } + + /// + /// 恢复播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + public void Resume(float fadeInSeconds) + { + m_SoundAgentHelper.Resume(fadeInSeconds); + } + + /// + /// 重置声音代理。 + /// + public void Reset() + { + if (m_SoundAsset != null) + { + m_SoundHelper.ReleaseSoundAsset(m_SoundAsset); + m_SoundAsset = null; + } + + m_SetSoundAssetTime = DateTime.MinValue; + Time = Constant.DefaultTime; + MuteInSoundGroup = Constant.DefaultMute; + Loop = Constant.DefaultLoop; + Priority = Constant.DefaultPriority; + VolumeInSoundGroup = Constant.DefaultVolume; + Pitch = Constant.DefaultPitch; + PanStereo = Constant.DefaultPanStereo; + SpatialBlend = Constant.DefaultSpatialBlend; + MaxDistance = Constant.DefaultMaxDistance; + DopplerLevel = Constant.DefaultDopplerLevel; + m_SoundAgentHelper.Reset(); + } + + internal bool SetSoundAsset(object soundAsset) + { + Reset(); + m_SoundAsset = soundAsset; + m_SetSoundAssetTime = DateTime.UtcNow; + return m_SoundAgentHelper.SetSoundAsset(soundAsset); + } + + internal void RefreshMute() + { + m_SoundAgentHelper.Mute = m_SoundGroup.Mute || m_MuteInSoundGroup; + } + + internal void RefreshVolume() + { + m_SoundAgentHelper.Volume = m_SoundGroup.Volume * m_VolumeInSoundGroup; + } + + private void OnResetSoundAgent(object sender, ResetSoundAgentEventArgs e) + { + Reset(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundAgent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundAgent.cs.meta new file mode 100644 index 0000000..cf494bc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundAgent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: adbc4a010dea15343a0f5cf0e94d7bb1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundGroup.cs new file mode 100644 index 0000000..229a563 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundGroup.cs @@ -0,0 +1,303 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.Sound +{ + internal sealed partial class SoundManager : GameFrameworkModule, ISoundManager + { + /// + /// 声音组。 + /// + private sealed class SoundGroup : ISoundGroup + { + private readonly string m_Name; + private readonly ISoundGroupHelper m_SoundGroupHelper; + private readonly List m_SoundAgents; + private bool m_AvoidBeingReplacedBySamePriority; + private bool m_Mute; + private float m_Volume; + + /// + /// 初始化声音组的新实例。 + /// + /// 声音组名称。 + /// 声音组辅助器。 + public SoundGroup(string name, ISoundGroupHelper soundGroupHelper) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("Sound group name is invalid."); + } + + if (soundGroupHelper == null) + { + throw new GameFrameworkException("Sound group helper is invalid."); + } + + m_Name = name; + m_SoundGroupHelper = soundGroupHelper; + m_SoundAgents = new List(); + } + + /// + /// 获取声音组名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取声音代理数。 + /// + public int SoundAgentCount + { + get + { + return m_SoundAgents.Count; + } + } + + /// + /// 获取或设置声音组中的声音是否避免被同优先级声音替换。 + /// + public bool AvoidBeingReplacedBySamePriority + { + get + { + return m_AvoidBeingReplacedBySamePriority; + } + set + { + m_AvoidBeingReplacedBySamePriority = value; + } + } + + /// + /// 获取或设置声音组静音。 + /// + public bool Mute + { + get + { + return m_Mute; + } + set + { + m_Mute = value; + foreach (SoundAgent soundAgent in m_SoundAgents) + { + soundAgent.RefreshMute(); + } + } + } + + /// + /// 获取或设置声音组音量。 + /// + public float Volume + { + get + { + return m_Volume; + } + set + { + m_Volume = value; + foreach (SoundAgent soundAgent in m_SoundAgents) + { + soundAgent.RefreshVolume(); + } + } + } + + /// + /// 获取声音组辅助器。 + /// + public ISoundGroupHelper Helper + { + get + { + return m_SoundGroupHelper; + } + } + + /// + /// 增加声音代理辅助器。 + /// + /// 声音辅助器接口。 + /// 要增加的声音代理辅助器。 + public void AddSoundAgentHelper(ISoundHelper soundHelper, ISoundAgentHelper soundAgentHelper) + { + m_SoundAgents.Add(new SoundAgent(this, soundHelper, soundAgentHelper)); + } + + /// + /// 播放声音。 + /// + /// 声音的序列编号。 + /// 声音资源。 + /// 播放声音参数。 + /// 错误码。 + /// 用于播放的声音代理。 + public ISoundAgent PlaySound(int serialId, object soundAsset, PlaySoundParams playSoundParams, out PlaySoundErrorCode? errorCode) + { + errorCode = null; + SoundAgent candidateAgent = null; + foreach (SoundAgent soundAgent in m_SoundAgents) + { + if (!soundAgent.IsPlaying) + { + candidateAgent = soundAgent; + break; + } + + if (soundAgent.Priority < playSoundParams.Priority) + { + if (candidateAgent == null || soundAgent.Priority < candidateAgent.Priority) + { + candidateAgent = soundAgent; + } + } + else if (!m_AvoidBeingReplacedBySamePriority && soundAgent.Priority == playSoundParams.Priority) + { + if (candidateAgent == null || soundAgent.SetSoundAssetTime < candidateAgent.SetSoundAssetTime) + { + candidateAgent = soundAgent; + } + } + } + + if (candidateAgent == null) + { + errorCode = PlaySoundErrorCode.IgnoredDueToLowPriority; + return null; + } + + if (!candidateAgent.SetSoundAsset(soundAsset)) + { + errorCode = PlaySoundErrorCode.SetSoundAssetFailure; + return null; + } + + candidateAgent.SerialId = serialId; + candidateAgent.Time = playSoundParams.Time; + candidateAgent.MuteInSoundGroup = playSoundParams.MuteInSoundGroup; + candidateAgent.Loop = playSoundParams.Loop; + candidateAgent.Priority = playSoundParams.Priority; + candidateAgent.VolumeInSoundGroup = playSoundParams.VolumeInSoundGroup; + candidateAgent.Pitch = playSoundParams.Pitch; + candidateAgent.PanStereo = playSoundParams.PanStereo; + candidateAgent.SpatialBlend = playSoundParams.SpatialBlend; + candidateAgent.MaxDistance = playSoundParams.MaxDistance; + candidateAgent.DopplerLevel = playSoundParams.DopplerLevel; + candidateAgent.Play(playSoundParams.FadeInSeconds); + return candidateAgent; + } + + /// + /// 停止播放声音。 + /// + /// 要停止播放声音的序列编号。 + /// 声音淡出时间,以秒为单位。 + /// 是否停止播放声音成功。 + public bool StopSound(int serialId, float fadeOutSeconds) + { + foreach (SoundAgent soundAgent in m_SoundAgents) + { + if (soundAgent.SerialId != serialId) + { + continue; + } + + soundAgent.Stop(fadeOutSeconds); + return true; + } + + return false; + } + + /// + /// 暂停播放声音。 + /// + /// 要暂停播放声音的序列编号。 + /// 声音淡出时间,以秒为单位。 + /// 是否暂停播放声音成功。 + public bool PauseSound(int serialId, float fadeOutSeconds) + { + foreach (SoundAgent soundAgent in m_SoundAgents) + { + if (soundAgent.SerialId != serialId) + { + continue; + } + + soundAgent.Pause(fadeOutSeconds); + return true; + } + + return false; + } + + /// + /// 恢复播放声音。 + /// + /// 要恢复播放声音的序列编号。 + /// 声音淡入时间,以秒为单位。 + /// 是否恢复播放声音成功。 + public bool ResumeSound(int serialId, float fadeInSeconds) + { + foreach (SoundAgent soundAgent in m_SoundAgents) + { + if (soundAgent.SerialId != serialId) + { + continue; + } + + soundAgent.Resume(fadeInSeconds); + return true; + } + + return false; + } + + /// + /// 停止所有已加载的声音。 + /// + public void StopAllLoadedSounds() + { + foreach (SoundAgent soundAgent in m_SoundAgents) + { + if (soundAgent.IsPlaying) + { + soundAgent.Stop(); + } + } + } + + /// + /// 停止所有已加载的声音。 + /// + /// 声音淡出时间,以秒为单位。 + public void StopAllLoadedSounds(float fadeOutSeconds) + { + foreach (SoundAgent soundAgent in m_SoundAgents) + { + if (soundAgent.IsPlaying) + { + soundAgent.Stop(fadeOutSeconds); + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundGroup.cs.meta new file mode 100644 index 0000000..6471acc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.SoundGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c67bf707bde88ad4d863398b2246312c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.cs new file mode 100644 index 0000000..827bf89 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.cs @@ -0,0 +1,754 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.Sound +{ + /// + /// 声音管理器。 + /// + internal sealed partial class SoundManager : GameFrameworkModule, ISoundManager + { + private readonly Dictionary m_SoundGroups; + private readonly List m_SoundsBeingLoaded; + private readonly HashSet m_SoundsToReleaseOnLoad; + private readonly LoadAssetCallbacks m_LoadAssetCallbacks; + private IResourceManager m_ResourceManager; + private ISoundHelper m_SoundHelper; + private int m_Serial; + private EventHandler m_PlaySoundSuccessEventHandler; + private EventHandler m_PlaySoundFailureEventHandler; + private EventHandler m_PlaySoundUpdateEventHandler; + private EventHandler m_PlaySoundDependencyAssetEventHandler; + + /// + /// 初始化声音管理器的新实例。 + /// + public SoundManager() + { + m_SoundGroups = new Dictionary(StringComparer.Ordinal); + m_SoundsBeingLoaded = new List(); + m_SoundsToReleaseOnLoad = new HashSet(); + m_LoadAssetCallbacks = new LoadAssetCallbacks(LoadAssetSuccessCallback, LoadAssetFailureCallback, LoadAssetUpdateCallback, LoadAssetDependencyAssetCallback); + m_ResourceManager = null; + m_SoundHelper = null; + m_Serial = 0; + m_PlaySoundSuccessEventHandler = null; + m_PlaySoundFailureEventHandler = null; + m_PlaySoundUpdateEventHandler = null; + m_PlaySoundDependencyAssetEventHandler = null; + } + + /// + /// 获取声音组数量。 + /// + public int SoundGroupCount + { + get + { + return m_SoundGroups.Count; + } + } + + /// + /// 播放声音成功事件。 + /// + public event EventHandler PlaySoundSuccess + { + add + { + m_PlaySoundSuccessEventHandler += value; + } + remove + { + m_PlaySoundSuccessEventHandler -= value; + } + } + + /// + /// 播放声音失败事件。 + /// + public event EventHandler PlaySoundFailure + { + add + { + m_PlaySoundFailureEventHandler += value; + } + remove + { + m_PlaySoundFailureEventHandler -= value; + } + } + + /// + /// 播放声音更新事件。 + /// + public event EventHandler PlaySoundUpdate + { + add + { + m_PlaySoundUpdateEventHandler += value; + } + remove + { + m_PlaySoundUpdateEventHandler -= value; + } + } + + /// + /// 播放声音时加载依赖资源事件。 + /// + public event EventHandler PlaySoundDependencyAsset + { + add + { + m_PlaySoundDependencyAssetEventHandler += value; + } + remove + { + m_PlaySoundDependencyAssetEventHandler -= value; + } + } + + /// + /// 声音管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 关闭并清理声音管理器。 + /// + internal override void Shutdown() + { + StopAllLoadedSounds(); + m_SoundGroups.Clear(); + m_SoundsBeingLoaded.Clear(); + m_SoundsToReleaseOnLoad.Clear(); + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + public void SetResourceManager(IResourceManager resourceManager) + { + if (resourceManager == null) + { + throw new GameFrameworkException("Resource manager is invalid."); + } + + m_ResourceManager = resourceManager; + } + + /// + /// 设置声音辅助器。 + /// + /// 声音辅助器。 + public void SetSoundHelper(ISoundHelper soundHelper) + { + if (soundHelper == null) + { + throw new GameFrameworkException("Sound helper is invalid."); + } + + m_SoundHelper = soundHelper; + } + + /// + /// 是否存在指定声音组。 + /// + /// 声音组名称。 + /// 指定声音组是否存在。 + public bool HasSoundGroup(string soundGroupName) + { + if (string.IsNullOrEmpty(soundGroupName)) + { + throw new GameFrameworkException("Sound group name is invalid."); + } + + return m_SoundGroups.ContainsKey(soundGroupName); + } + + /// + /// 获取指定声音组。 + /// + /// 声音组名称。 + /// 要获取的声音组。 + public ISoundGroup GetSoundGroup(string soundGroupName) + { + if (string.IsNullOrEmpty(soundGroupName)) + { + throw new GameFrameworkException("Sound group name is invalid."); + } + + SoundGroup soundGroup = null; + if (m_SoundGroups.TryGetValue(soundGroupName, out soundGroup)) + { + return soundGroup; + } + + return null; + } + + /// + /// 获取所有声音组。 + /// + /// 所有声音组。 + public ISoundGroup[] GetAllSoundGroups() + { + int index = 0; + ISoundGroup[] results = new ISoundGroup[m_SoundGroups.Count]; + foreach (KeyValuePair soundGroup in m_SoundGroups) + { + results[index++] = soundGroup.Value; + } + + return results; + } + + /// + /// 获取所有声音组。 + /// + /// 所有声音组。 + public void GetAllSoundGroups(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair soundGroup in m_SoundGroups) + { + results.Add(soundGroup.Value); + } + } + + /// + /// 增加声音组。 + /// + /// 声音组名称。 + /// 声音组辅助器。 + /// 是否增加声音组成功。 + public bool AddSoundGroup(string soundGroupName, ISoundGroupHelper soundGroupHelper) + { + return AddSoundGroup(soundGroupName, false, Constant.DefaultMute, Constant.DefaultVolume, soundGroupHelper); + } + + /// + /// 增加声音组。 + /// + /// 声音组名称。 + /// 声音组中的声音是否避免被同优先级声音替换。 + /// 声音组是否静音。 + /// 声音组音量。 + /// 声音组辅助器。 + /// 是否增加声音组成功。 + public bool AddSoundGroup(string soundGroupName, bool soundGroupAvoidBeingReplacedBySamePriority, bool soundGroupMute, float soundGroupVolume, ISoundGroupHelper soundGroupHelper) + { + if (string.IsNullOrEmpty(soundGroupName)) + { + throw new GameFrameworkException("Sound group name is invalid."); + } + + if (soundGroupHelper == null) + { + throw new GameFrameworkException("Sound group helper is invalid."); + } + + if (HasSoundGroup(soundGroupName)) + { + return false; + } + + SoundGroup soundGroup = new SoundGroup(soundGroupName, soundGroupHelper) + { + AvoidBeingReplacedBySamePriority = soundGroupAvoidBeingReplacedBySamePriority, + Mute = soundGroupMute, + Volume = soundGroupVolume + }; + + m_SoundGroups.Add(soundGroupName, soundGroup); + + return true; + } + + /// + /// 增加声音代理辅助器。 + /// + /// 声音组名称。 + /// 要增加的声音代理辅助器。 + public void AddSoundAgentHelper(string soundGroupName, ISoundAgentHelper soundAgentHelper) + { + if (m_SoundHelper == null) + { + throw new GameFrameworkException("You must set sound helper first."); + } + + SoundGroup soundGroup = (SoundGroup)GetSoundGroup(soundGroupName); + if (soundGroup == null) + { + throw new GameFrameworkException(Utility.Text.Format("Sound group '{0}' is not exist.", soundGroupName)); + } + + soundGroup.AddSoundAgentHelper(m_SoundHelper, soundAgentHelper); + } + + /// + /// 获取所有正在加载声音的序列编号。 + /// + /// 所有正在加载声音的序列编号。 + public int[] GetAllLoadingSoundSerialIds() + { + return m_SoundsBeingLoaded.ToArray(); + } + + /// + /// 获取所有正在加载声音的序列编号。 + /// + /// 所有正在加载声音的序列编号。 + public void GetAllLoadingSoundSerialIds(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + results.AddRange(m_SoundsBeingLoaded); + } + + /// + /// 是否正在加载声音。 + /// + /// 声音序列编号。 + /// 是否正在加载声音。 + public bool IsLoadingSound(int serialId) + { + return m_SoundsBeingLoaded.Contains(serialId); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName) + { + return PlaySound(soundAssetName, soundGroupName, Resource.Constant.DefaultPriority, null, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority) + { + return PlaySound(soundAssetName, soundGroupName, priority, null, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 播放声音参数。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, PlaySoundParams playSoundParams) + { + return PlaySound(soundAssetName, soundGroupName, Resource.Constant.DefaultPriority, playSoundParams, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 用户自定义数据。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, object userData) + { + return PlaySound(soundAssetName, soundGroupName, Resource.Constant.DefaultPriority, null, userData); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams) + { + return PlaySound(soundAssetName, soundGroupName, priority, playSoundParams, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 用户自定义数据。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, object userData) + { + return PlaySound(soundAssetName, soundGroupName, priority, null, userData); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 播放声音参数。 + /// 用户自定义数据。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, PlaySoundParams playSoundParams, object userData) + { + return PlaySound(soundAssetName, soundGroupName, Resource.Constant.DefaultPriority, playSoundParams, userData); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 用户自定义数据。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams, object userData) + { + if (m_ResourceManager == null) + { + throw new GameFrameworkException("You must set resource manager first."); + } + + if (m_SoundHelper == null) + { + throw new GameFrameworkException("You must set sound helper first."); + } + + if (playSoundParams == null) + { + playSoundParams = PlaySoundParams.Create(); + } + + int serialId = ++m_Serial; + PlaySoundErrorCode? errorCode = null; + string errorMessage = null; + SoundGroup soundGroup = (SoundGroup)GetSoundGroup(soundGroupName); + if (soundGroup == null) + { + errorCode = PlaySoundErrorCode.SoundGroupNotExist; + errorMessage = Utility.Text.Format("Sound group '{0}' is not exist.", soundGroupName); + } + else if (soundGroup.SoundAgentCount <= 0) + { + errorCode = PlaySoundErrorCode.SoundGroupHasNoAgent; + errorMessage = Utility.Text.Format("Sound group '{0}' is have no sound agent.", soundGroupName); + } + + if (errorCode.HasValue) + { + if (m_PlaySoundFailureEventHandler != null) + { + PlaySoundFailureEventArgs playSoundFailureEventArgs = PlaySoundFailureEventArgs.Create(serialId, soundAssetName, soundGroupName, playSoundParams, errorCode.Value, errorMessage, userData); + m_PlaySoundFailureEventHandler(this, playSoundFailureEventArgs); + ReferencePool.Release(playSoundFailureEventArgs); + + if (playSoundParams.Referenced) + { + ReferencePool.Release(playSoundParams); + } + + return serialId; + } + + throw new GameFrameworkException(errorMessage); + } + + m_SoundsBeingLoaded.Add(serialId); + m_ResourceManager.LoadAsset(soundAssetName, priority, m_LoadAssetCallbacks, PlaySoundInfo.Create(serialId, soundGroup, playSoundParams, userData)); + return serialId; + } + + /// + /// 停止播放声音。 + /// + /// 要停止播放声音的序列编号。 + /// 是否停止播放声音成功。 + public bool StopSound(int serialId) + { + return StopSound(serialId, Constant.DefaultFadeOutSeconds); + } + + /// + /// 停止播放声音。 + /// + /// 要停止播放声音的序列编号。 + /// 声音淡出时间,以秒为单位。 + /// 是否停止播放声音成功。 + public bool StopSound(int serialId, float fadeOutSeconds) + { + if (IsLoadingSound(serialId)) + { + m_SoundsToReleaseOnLoad.Add(serialId); + m_SoundsBeingLoaded.Remove(serialId); + return true; + } + + foreach (KeyValuePair soundGroup in m_SoundGroups) + { + if (soundGroup.Value.StopSound(serialId, fadeOutSeconds)) + { + return true; + } + } + + return false; + } + + /// + /// 停止所有已加载的声音。 + /// + public void StopAllLoadedSounds() + { + StopAllLoadedSounds(Constant.DefaultFadeOutSeconds); + } + + /// + /// 停止所有已加载的声音。 + /// + /// 声音淡出时间,以秒为单位。 + public void StopAllLoadedSounds(float fadeOutSeconds) + { + foreach (KeyValuePair soundGroup in m_SoundGroups) + { + soundGroup.Value.StopAllLoadedSounds(fadeOutSeconds); + } + } + + /// + /// 停止所有正在加载的声音。 + /// + public void StopAllLoadingSounds() + { + foreach (int serialId in m_SoundsBeingLoaded) + { + m_SoundsToReleaseOnLoad.Add(serialId); + } + } + + /// + /// 暂停播放声音。 + /// + /// 要暂停播放声音的序列编号。 + public void PauseSound(int serialId) + { + PauseSound(serialId, Constant.DefaultFadeOutSeconds); + } + + /// + /// 暂停播放声音。 + /// + /// 要暂停播放声音的序列编号。 + /// 声音淡出时间,以秒为单位。 + public void PauseSound(int serialId, float fadeOutSeconds) + { + foreach (KeyValuePair soundGroup in m_SoundGroups) + { + if (soundGroup.Value.PauseSound(serialId, fadeOutSeconds)) + { + return; + } + } + + throw new GameFrameworkException(Utility.Text.Format("Can not find sound '{0}'.", serialId)); + } + + /// + /// 恢复播放声音。 + /// + /// 要恢复播放声音的序列编号。 + public void ResumeSound(int serialId) + { + ResumeSound(serialId, Constant.DefaultFadeInSeconds); + } + + /// + /// 恢复播放声音。 + /// + /// 要恢复播放声音的序列编号。 + /// 声音淡入时间,以秒为单位。 + public void ResumeSound(int serialId, float fadeInSeconds) + { + foreach (KeyValuePair soundGroup in m_SoundGroups) + { + if (soundGroup.Value.ResumeSound(serialId, fadeInSeconds)) + { + return; + } + } + + throw new GameFrameworkException(Utility.Text.Format("Can not find sound '{0}'.", serialId)); + } + + private void LoadAssetSuccessCallback(string soundAssetName, object soundAsset, float duration, object userData) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)userData; + if (playSoundInfo == null) + { + throw new GameFrameworkException("Play sound info is invalid."); + } + + if (m_SoundsToReleaseOnLoad.Contains(playSoundInfo.SerialId)) + { + m_SoundsToReleaseOnLoad.Remove(playSoundInfo.SerialId); + if (playSoundInfo.PlaySoundParams.Referenced) + { + ReferencePool.Release(playSoundInfo.PlaySoundParams); + } + + ReferencePool.Release(playSoundInfo); + m_SoundHelper.ReleaseSoundAsset(soundAsset); + return; + } + + m_SoundsBeingLoaded.Remove(playSoundInfo.SerialId); + + PlaySoundErrorCode? errorCode = null; + ISoundAgent soundAgent = playSoundInfo.SoundGroup.PlaySound(playSoundInfo.SerialId, soundAsset, playSoundInfo.PlaySoundParams, out errorCode); + if (soundAgent != null) + { + if (m_PlaySoundSuccessEventHandler != null) + { + PlaySoundSuccessEventArgs playSoundSuccessEventArgs = PlaySoundSuccessEventArgs.Create(playSoundInfo.SerialId, soundAssetName, soundAgent, duration, playSoundInfo.UserData); + m_PlaySoundSuccessEventHandler(this, playSoundSuccessEventArgs); + ReferencePool.Release(playSoundSuccessEventArgs); + } + + if (playSoundInfo.PlaySoundParams.Referenced) + { + ReferencePool.Release(playSoundInfo.PlaySoundParams); + } + + ReferencePool.Release(playSoundInfo); + return; + } + + m_SoundsToReleaseOnLoad.Remove(playSoundInfo.SerialId); + m_SoundHelper.ReleaseSoundAsset(soundAsset); + string errorMessage = Utility.Text.Format("Sound group '{0}' play sound '{1}' failure.", playSoundInfo.SoundGroup.Name, soundAssetName); + if (m_PlaySoundFailureEventHandler != null) + { + PlaySoundFailureEventArgs playSoundFailureEventArgs = PlaySoundFailureEventArgs.Create(playSoundInfo.SerialId, soundAssetName, playSoundInfo.SoundGroup.Name, playSoundInfo.PlaySoundParams, errorCode.Value, errorMessage, playSoundInfo.UserData); + m_PlaySoundFailureEventHandler(this, playSoundFailureEventArgs); + ReferencePool.Release(playSoundFailureEventArgs); + + if (playSoundInfo.PlaySoundParams.Referenced) + { + ReferencePool.Release(playSoundInfo.PlaySoundParams); + } + + ReferencePool.Release(playSoundInfo); + return; + } + + if (playSoundInfo.PlaySoundParams.Referenced) + { + ReferencePool.Release(playSoundInfo.PlaySoundParams); + } + + ReferencePool.Release(playSoundInfo); + throw new GameFrameworkException(errorMessage); + } + + private void LoadAssetFailureCallback(string soundAssetName, LoadResourceStatus status, string errorMessage, object userData) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)userData; + if (playSoundInfo == null) + { + throw new GameFrameworkException("Play sound info is invalid."); + } + + if (m_SoundsToReleaseOnLoad.Contains(playSoundInfo.SerialId)) + { + m_SoundsToReleaseOnLoad.Remove(playSoundInfo.SerialId); + if (playSoundInfo.PlaySoundParams.Referenced) + { + ReferencePool.Release(playSoundInfo.PlaySoundParams); + } + + return; + } + + m_SoundsBeingLoaded.Remove(playSoundInfo.SerialId); + string appendErrorMessage = Utility.Text.Format("Load sound failure, asset name '{0}', status '{1}', error message '{2}'.", soundAssetName, status, errorMessage); + if (m_PlaySoundFailureEventHandler != null) + { + PlaySoundFailureEventArgs playSoundFailureEventArgs = PlaySoundFailureEventArgs.Create(playSoundInfo.SerialId, soundAssetName, playSoundInfo.SoundGroup.Name, playSoundInfo.PlaySoundParams, PlaySoundErrorCode.LoadAssetFailure, appendErrorMessage, playSoundInfo.UserData); + m_PlaySoundFailureEventHandler(this, playSoundFailureEventArgs); + ReferencePool.Release(playSoundFailureEventArgs); + + if (playSoundInfo.PlaySoundParams.Referenced) + { + ReferencePool.Release(playSoundInfo.PlaySoundParams); + } + + return; + } + + throw new GameFrameworkException(appendErrorMessage); + } + + private void LoadAssetUpdateCallback(string soundAssetName, float progress, object userData) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)userData; + if (playSoundInfo == null) + { + throw new GameFrameworkException("Play sound info is invalid."); + } + + if (m_PlaySoundUpdateEventHandler != null) + { + PlaySoundUpdateEventArgs playSoundUpdateEventArgs = PlaySoundUpdateEventArgs.Create(playSoundInfo.SerialId, soundAssetName, playSoundInfo.SoundGroup.Name, playSoundInfo.PlaySoundParams, progress, playSoundInfo.UserData); + m_PlaySoundUpdateEventHandler(this, playSoundUpdateEventArgs); + ReferencePool.Release(playSoundUpdateEventArgs); + } + } + + private void LoadAssetDependencyAssetCallback(string soundAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)userData; + if (playSoundInfo == null) + { + throw new GameFrameworkException("Play sound info is invalid."); + } + + if (m_PlaySoundDependencyAssetEventHandler != null) + { + PlaySoundDependencyAssetEventArgs playSoundDependencyAssetEventArgs = PlaySoundDependencyAssetEventArgs.Create(playSoundInfo.SerialId, soundAssetName, playSoundInfo.SoundGroup.Name, playSoundInfo.PlaySoundParams, dependencyAssetName, loadedCount, totalCount, playSoundInfo.UserData); + m_PlaySoundDependencyAssetEventHandler(this, playSoundDependencyAssetEventArgs); + ReferencePool.Release(playSoundDependencyAssetEventArgs); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.cs.meta new file mode 100644 index 0000000..204a2ec --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Sound/SoundManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2820687499b14b346b37072be05c629c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI.meta new file mode 100644 index 0000000..d0946a6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4a77a3c43498445439b3e47be9042f7e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/CloseUIFormCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/CloseUIFormCompleteEventArgs.cs new file mode 100644 index 0000000..f1a4661 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/CloseUIFormCompleteEventArgs.cs @@ -0,0 +1,91 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + /// + /// 关闭界面完成事件。 + /// + public sealed class CloseUIFormCompleteEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化关闭界面完成事件的新实例。 + /// + public CloseUIFormCompleteEventArgs() + { + SerialId = 0; + UIFormAssetName = null; + UIGroup = null; + UserData = null; + } + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get; + private set; + } + + /// + /// 获取界面所属的界面组。 + /// + public IUIGroup UIGroup + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建关闭界面完成事件。 + /// + /// 界面序列编号。 + /// 界面资源名称。 + /// 界面所属的界面组。 + /// 用户自定义数据。 + /// 创建的关闭界面完成事件。 + public static CloseUIFormCompleteEventArgs Create(int serialId, string uiFormAssetName, IUIGroup uiGroup, object userData) + { + CloseUIFormCompleteEventArgs closeUIFormCompleteEventArgs = ReferencePool.Acquire(); + closeUIFormCompleteEventArgs.SerialId = serialId; + closeUIFormCompleteEventArgs.UIFormAssetName = uiFormAssetName; + closeUIFormCompleteEventArgs.UIGroup = uiGroup; + closeUIFormCompleteEventArgs.UserData = userData; + return closeUIFormCompleteEventArgs; + } + + /// + /// 清理关闭界面完成事件。 + /// + public override void Clear() + { + SerialId = 0; + UIFormAssetName = null; + UIGroup = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/CloseUIFormCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/CloseUIFormCompleteEventArgs.cs.meta new file mode 100644 index 0000000..6e9dd75 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/CloseUIFormCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cbf3474e96359d4b99fdebabb685881 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIForm.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIForm.cs new file mode 100644 index 0000000..3be19e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIForm.cs @@ -0,0 +1,132 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + /// + /// 界面接口。 + /// + public interface IUIForm + { + /// + /// 获取界面序列编号。 + /// + int SerialId + { + get; + } + + /// + /// 获取界面资源名称。 + /// + string UIFormAssetName + { + get; + } + + /// + /// 获取界面实例。 + /// + object Handle + { + get; + } + + /// + /// 获取界面所属的界面组。 + /// + IUIGroup UIGroup + { + get; + } + + /// + /// 获取界面在界面组中的深度。 + /// + int DepthInUIGroup + { + get; + } + + /// + /// 获取是否暂停被覆盖的界面。 + /// + bool PauseCoveredUIForm + { + get; + } + + /// + /// 初始化界面。 + /// + /// 界面序列编号。 + /// 界面资源名称。 + /// 界面所属的界面组。 + /// 是否暂停被覆盖的界面。 + /// 是否是新实例。 + /// 用户自定义数据。 + void OnInit(int serialId, string uiFormAssetName, IUIGroup uiGroup, bool pauseCoveredUIForm, bool isNewInstance, object userData); + + /// + /// 界面回收。 + /// + void OnRecycle(); + + /// + /// 界面打开。 + /// + /// 用户自定义数据。 + void OnOpen(object userData); + + /// + /// 界面关闭。 + /// + /// 是否是关闭界面管理器时触发。 + /// 用户自定义数据。 + void OnClose(bool isShutdown, object userData); + + /// + /// 界面暂停。 + /// + void OnPause(); + + /// + /// 界面暂停恢复。 + /// + void OnResume(); + + /// + /// 界面遮挡。 + /// + void OnCover(); + + /// + /// 界面遮挡恢复。 + /// + void OnReveal(); + + /// + /// 界面激活。 + /// + /// 用户自定义数据。 + void OnRefocus(object userData); + + /// + /// 界面轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + void OnUpdate(float elapseSeconds, float realElapseSeconds); + + /// + /// 界面深度改变。 + /// + /// 界面组深度。 + /// 界面在界面组中的深度。 + void OnDepthChanged(int uiGroupDepth, int depthInUIGroup); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIForm.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIForm.cs.meta new file mode 100644 index 0000000..367270b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIForm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a860fa2f69283745a496a1082b1f2d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIFormHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIFormHelper.cs new file mode 100644 index 0000000..6362107 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIFormHelper.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + /// + /// 界面辅助器接口。 + /// + public interface IUIFormHelper + { + /// + /// 实例化界面。 + /// + /// 要实例化的界面资源。 + /// 实例化后的界面。 + object InstantiateUIForm(object uiFormAsset); + + /// + /// 创建界面。 + /// + /// 界面实例。 + /// 界面所属的界面组。 + /// 用户自定义数据。 + /// 界面。 + IUIForm CreateUIForm(object uiFormInstance, IUIGroup uiGroup, object userData); + + /// + /// 释放界面。 + /// + /// 要释放的界面资源。 + /// 要释放的界面实例。 + void ReleaseUIForm(object uiFormAsset, object uiFormInstance); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIFormHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIFormHelper.cs.meta new file mode 100644 index 0000000..c33a058 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIFormHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 18d585b155a36234f9b30fa4140918c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroup.cs new file mode 100644 index 0000000..a2a04db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroup.cs @@ -0,0 +1,121 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.UI +{ + /// + /// 界面组接口。 + /// + public interface IUIGroup + { + /// + /// 获取界面组名称。 + /// + string Name + { + get; + } + + /// + /// 获取或设置界面组深度。 + /// + int Depth + { + get; + set; + } + + /// + /// 获取或设置界面组是否暂停。 + /// + bool Pause + { + get; + set; + } + + /// + /// 获取界面组中界面数量。 + /// + int UIFormCount + { + get; + } + + /// + /// 获取当前界面。 + /// + IUIForm CurrentUIForm + { + get; + } + + /// + /// 获取界面组辅助器。 + /// + IUIGroupHelper Helper + { + get; + } + + /// + /// 界面组中是否存在界面。 + /// + /// 界面序列编号。 + /// 界面组中是否存在界面。 + bool HasUIForm(int serialId); + + /// + /// 界面组中是否存在界面。 + /// + /// 界面资源名称。 + /// 界面组中是否存在界面。 + bool HasUIForm(string uiFormAssetName); + + /// + /// 从界面组中获取界面。 + /// + /// 界面序列编号。 + /// 要获取的界面。 + IUIForm GetUIForm(int serialId); + + /// + /// 从界面组中获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + IUIForm GetUIForm(string uiFormAssetName); + + /// + /// 从界面组中获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + IUIForm[] GetUIForms(string uiFormAssetName); + + /// + /// 从界面组中获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + void GetUIForms(string uiFormAssetName, List results); + + /// + /// 从界面组中获取所有界面。 + /// + /// 界面组中的所有界面。 + IUIForm[] GetAllUIForms(); + + /// + /// 从界面组中获取所有界面。 + /// + /// 界面组中的所有界面。 + void GetAllUIForms(List results); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroup.cs.meta new file mode 100644 index 0000000..d6ab36c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2322522491c53b64b8eb5d74643dbbdd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroupHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroupHelper.cs new file mode 100644 index 0000000..f3ba600 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroupHelper.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + /// + /// 界面组辅助器接口。 + /// + public interface IUIGroupHelper + { + /// + /// 设置界面组深度。 + /// + /// 界面组深度。 + void SetDepth(int depth); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroupHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroupHelper.cs.meta new file mode 100644 index 0000000..27b3c4a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIGroupHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd7688a03213482438d4e366309f9131 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIManager.cs new file mode 100644 index 0000000..c0d213b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIManager.cs @@ -0,0 +1,382 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.UI +{ + /// + /// 界面管理器接口。 + /// + public interface IUIManager + { + /// + /// 获取界面组数量。 + /// + int UIGroupCount + { + get; + } + + /// + /// 获取或设置界面实例对象池自动释放可释放对象的间隔秒数。 + /// + float InstanceAutoReleaseInterval + { + get; + set; + } + + /// + /// 获取或设置界面实例对象池的容量。 + /// + int InstanceCapacity + { + get; + set; + } + + /// + /// 获取或设置界面实例对象池对象过期秒数。 + /// + float InstanceExpireTime + { + get; + set; + } + + /// + /// 获取或设置界面实例对象池的优先级。 + /// + int InstancePriority + { + get; + set; + } + + /// + /// 打开界面成功事件。 + /// + event EventHandler OpenUIFormSuccess; + + /// + /// 打开界面失败事件。 + /// + event EventHandler OpenUIFormFailure; + + /// + /// 打开界面更新事件。 + /// + event EventHandler OpenUIFormUpdate; + + /// + /// 打开界面时加载依赖资源事件。 + /// + event EventHandler OpenUIFormDependencyAsset; + + /// + /// 关闭界面完成事件。 + /// + event EventHandler CloseUIFormComplete; + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + void SetObjectPoolManager(IObjectPoolManager objectPoolManager); + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + void SetResourceManager(IResourceManager resourceManager); + + /// + /// 设置界面辅助器。 + /// + /// 界面辅助器。 + void SetUIFormHelper(IUIFormHelper uiFormHelper); + + /// + /// 是否存在界面组。 + /// + /// 界面组名称。 + /// 是否存在界面组。 + bool HasUIGroup(string uiGroupName); + + /// + /// 获取界面组。 + /// + /// 界面组名称。 + /// 要获取的界面组。 + IUIGroup GetUIGroup(string uiGroupName); + + /// + /// 获取所有界面组。 + /// + /// 所有界面组。 + IUIGroup[] GetAllUIGroups(); + + /// + /// 获取所有界面组。 + /// + /// 所有界面组。 + void GetAllUIGroups(List results); + + /// + /// 增加界面组。 + /// + /// 界面组名称。 + /// 界面组辅助器。 + /// 是否增加界面组成功。 + bool AddUIGroup(string uiGroupName, IUIGroupHelper uiGroupHelper); + + /// + /// 增加界面组。 + /// + /// 界面组名称。 + /// 界面组深度。 + /// 界面组辅助器。 + /// 是否增加界面组成功。 + bool AddUIGroup(string uiGroupName, int uiGroupDepth, IUIGroupHelper uiGroupHelper); + + /// + /// 是否存在界面。 + /// + /// 界面序列编号。 + /// 是否存在界面。 + bool HasUIForm(int serialId); + + /// + /// 是否存在界面。 + /// + /// 界面资源名称。 + /// 是否存在界面。 + bool HasUIForm(string uiFormAssetName); + + /// + /// 获取界面。 + /// + /// 界面序列编号。 + /// 要获取的界面。 + IUIForm GetUIForm(int serialId); + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + IUIForm GetUIForm(string uiFormAssetName); + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + IUIForm[] GetUIForms(string uiFormAssetName); + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + void GetUIForms(string uiFormAssetName, List results); + + /// + /// 获取所有已加载的界面。 + /// + /// 所有已加载的界面。 + IUIForm[] GetAllLoadedUIForms(); + + /// + /// 获取所有已加载的界面。 + /// + /// 所有已加载的界面。 + void GetAllLoadedUIForms(List results); + + /// + /// 获取所有正在加载界面的序列编号。 + /// + /// 所有正在加载界面的序列编号。 + int[] GetAllLoadingUIFormSerialIds(); + + /// + /// 获取所有正在加载界面的序列编号。 + /// + /// 所有正在加载界面的序列编号。 + void GetAllLoadingUIFormSerialIds(List results); + + /// + /// 是否正在加载界面。 + /// + /// 界面序列编号。 + /// 是否正在加载界面。 + bool IsLoadingUIForm(int serialId); + + /// + /// 是否正在加载界面。 + /// + /// 界面资源名称。 + /// 是否正在加载界面。 + bool IsLoadingUIForm(string uiFormAssetName); + + /// + /// 是否是合法的界面。 + /// + /// 界面。 + /// 界面是否合法。 + bool IsValidUIForm(IUIForm uiForm); + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 界面的序列编号。 + int OpenUIForm(string uiFormAssetName, string uiGroupName); + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 界面的序列编号。 + int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority); + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 界面的序列编号。 + int OpenUIForm(string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm); + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 用户自定义数据。 + /// 界面的序列编号。 + int OpenUIForm(string uiFormAssetName, string uiGroupName, object userData); + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 是否暂停被覆盖的界面。 + /// 界面的序列编号。 + int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm); + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 用户自定义数据。 + /// 界面的序列编号。 + int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, object userData); + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 用户自定义数据。 + /// 界面的序列编号。 + int OpenUIForm(string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm, object userData); + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 是否暂停被覆盖的界面。 + /// 用户自定义数据。 + /// 界面的序列编号。 + int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm, object userData); + + /// + /// 关闭界面。 + /// + /// 要关闭界面的序列编号。 + void CloseUIForm(int serialId); + + /// + /// 关闭界面。 + /// + /// 要关闭界面的序列编号。 + /// 用户自定义数据。 + void CloseUIForm(int serialId, object userData); + + /// + /// 关闭界面。 + /// + /// 要关闭的界面。 + void CloseUIForm(IUIForm uiForm); + + /// + /// 关闭界面。 + /// + /// 要关闭的界面。 + /// 用户自定义数据。 + void CloseUIForm(IUIForm uiForm, object userData); + + /// + /// 关闭所有已加载的界面。 + /// + void CloseAllLoadedUIForms(); + + /// + /// 关闭所有已加载的界面。 + /// + /// 用户自定义数据。 + void CloseAllLoadedUIForms(object userData); + + /// + /// 关闭所有正在加载的界面。 + /// + void CloseAllLoadingUIForms(); + + /// + /// 激活界面。 + /// + /// 要激活的界面。 + void RefocusUIForm(IUIForm uiForm); + + /// + /// 激活界面。 + /// + /// 要激活的界面。 + /// 用户自定义数据。 + void RefocusUIForm(IUIForm uiForm, object userData); + + /// + /// 设置界面实例是否被加锁。 + /// + /// 要设置是否被加锁的界面实例。 + /// 界面实例是否被加锁。 + void SetUIFormInstanceLocked(object uiFormInstance, bool locked); + + /// + /// 设置界面实例的优先级。 + /// + /// 要设置优先级的界面实例。 + /// 界面实例优先级。 + void SetUIFormInstancePriority(object uiFormInstance, int priority); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIManager.cs.meta new file mode 100644 index 0000000..3553eba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/IUIManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26b7d8cac1c122a499874e612f6fbddc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs new file mode 100644 index 0000000..0a483c5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs @@ -0,0 +1,143 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + /// + /// 打开界面时加载依赖资源事件。 + /// + public sealed class OpenUIFormDependencyAssetEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化打开界面时加载依赖资源事件的新实例。 + /// + public OpenUIFormDependencyAssetEventArgs() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get; + private set; + } + + /// + /// 获取界面组名称。 + /// + public string UIGroupName + { + get; + private set; + } + + /// + /// 获取是否暂停被覆盖的界面。 + /// + public bool PauseCoveredUIForm + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建打开界面时加载依赖资源事件。 + /// + /// 界面序列编号。 + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 被加载的依赖资源名称。 + /// 当前已加载依赖资源数量。 + /// 总共加载依赖资源数量。 + /// 用户自定义数据。 + /// 创建的打开界面时加载依赖资源事件。 + public static OpenUIFormDependencyAssetEventArgs Create(int serialId, string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + OpenUIFormDependencyAssetEventArgs openUIFormDependencyAssetEventArgs = ReferencePool.Acquire(); + openUIFormDependencyAssetEventArgs.SerialId = serialId; + openUIFormDependencyAssetEventArgs.UIFormAssetName = uiFormAssetName; + openUIFormDependencyAssetEventArgs.UIGroupName = uiGroupName; + openUIFormDependencyAssetEventArgs.PauseCoveredUIForm = pauseCoveredUIForm; + openUIFormDependencyAssetEventArgs.DependencyAssetName = dependencyAssetName; + openUIFormDependencyAssetEventArgs.LoadedCount = loadedCount; + openUIFormDependencyAssetEventArgs.TotalCount = totalCount; + openUIFormDependencyAssetEventArgs.UserData = userData; + return openUIFormDependencyAssetEventArgs; + } + + /// + /// 清理打开界面时加载依赖资源事件。 + /// + public override void Clear() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..e4494f7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b9f70354d8cdf04dac55cb6c02df75b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormFailureEventArgs.cs new file mode 100644 index 0000000..824eef4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormFailureEventArgs.cs @@ -0,0 +1,117 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + /// + /// 打开界面失败事件。 + /// + public sealed class OpenUIFormFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化打开界面失败事件的新实例。 + /// + public OpenUIFormFailureEventArgs() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get; + private set; + } + + /// + /// 获取界面组名称。 + /// + public string UIGroupName + { + get; + private set; + } + + /// + /// 获取是否暂停被覆盖的界面。 + /// + public bool PauseCoveredUIForm + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建打开界面失败事件。 + /// + /// 界面序列编号。 + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 错误信息。 + /// 用户自定义数据。 + /// 创建的打开界面失败事件。 + public static OpenUIFormFailureEventArgs Create(int serialId, string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm, string errorMessage, object userData) + { + OpenUIFormFailureEventArgs openUIFormFailureEventArgs = ReferencePool.Acquire(); + openUIFormFailureEventArgs.SerialId = serialId; + openUIFormFailureEventArgs.UIFormAssetName = uiFormAssetName; + openUIFormFailureEventArgs.UIGroupName = uiGroupName; + openUIFormFailureEventArgs.PauseCoveredUIForm = pauseCoveredUIForm; + openUIFormFailureEventArgs.ErrorMessage = errorMessage; + openUIFormFailureEventArgs.UserData = userData; + return openUIFormFailureEventArgs; + } + + /// + /// 清理打开界面失败事件。 + /// + public override void Clear() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormFailureEventArgs.cs.meta new file mode 100644 index 0000000..c1199d9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06dcc8caa7a2f034792b508ed67216f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormSuccessEventArgs.cs new file mode 100644 index 0000000..77fa499 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormSuccessEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + /// + /// 打开界面成功事件。 + /// + public sealed class OpenUIFormSuccessEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化打开界面成功事件的新实例。 + /// + public OpenUIFormSuccessEventArgs() + { + UIForm = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取打开成功的界面。 + /// + public IUIForm UIForm + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建打开界面成功事件。 + /// + /// 加载成功的界面。 + /// 加载持续时间。 + /// 用户自定义数据。 + /// 创建的打开界面成功事件。 + public static OpenUIFormSuccessEventArgs Create(IUIForm uiForm, float duration, object userData) + { + OpenUIFormSuccessEventArgs openUIFormSuccessEventArgs = ReferencePool.Acquire(); + openUIFormSuccessEventArgs.UIForm = uiForm; + openUIFormSuccessEventArgs.Duration = duration; + openUIFormSuccessEventArgs.UserData = userData; + return openUIFormSuccessEventArgs; + } + + /// + /// 清理打开界面成功事件。 + /// + public override void Clear() + { + UIForm = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormSuccessEventArgs.cs.meta new file mode 100644 index 0000000..569d698 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86756e33468c70042abe51b28effe2f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormUpdateEventArgs.cs new file mode 100644 index 0000000..70704e4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormUpdateEventArgs.cs @@ -0,0 +1,117 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + /// + /// 打开界面更新事件。 + /// + public sealed class OpenUIFormUpdateEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化打开界面更新事件的新实例。 + /// + public OpenUIFormUpdateEventArgs() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + Progress = 0f; + UserData = null; + } + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get; + private set; + } + + /// + /// 获取界面组名称。 + /// + public string UIGroupName + { + get; + private set; + } + + /// + /// 获取是否暂停被覆盖的界面。 + /// + public bool PauseCoveredUIForm + { + get; + private set; + } + + /// + /// 获取打开界面进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建打开界面更新事件。 + /// + /// 界面序列编号。 + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 打开界面进度。 + /// 用户自定义数据。 + /// 创建的打开界面更新事件。 + public static OpenUIFormUpdateEventArgs Create(int serialId, string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm, float progress, object userData) + { + OpenUIFormUpdateEventArgs openUIFormUpdateEventArgs = ReferencePool.Acquire(); + openUIFormUpdateEventArgs.SerialId = serialId; + openUIFormUpdateEventArgs.UIFormAssetName = uiFormAssetName; + openUIFormUpdateEventArgs.UIGroupName = uiGroupName; + openUIFormUpdateEventArgs.PauseCoveredUIForm = pauseCoveredUIForm; + openUIFormUpdateEventArgs.Progress = progress; + openUIFormUpdateEventArgs.UserData = userData; + return openUIFormUpdateEventArgs; + } + + /// + /// 清理打开界面更新事件。 + /// + public override void Clear() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormUpdateEventArgs.cs.meta new file mode 100644 index 0000000..0b31314 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/OpenUIFormUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef637eba3eeecdb4a93135f2c922e4ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.OpenUIFormInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.OpenUIFormInfo.cs new file mode 100644 index 0000000..c942aa5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.OpenUIFormInfo.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + internal sealed partial class UIManager : GameFrameworkModule, IUIManager + { + private sealed class OpenUIFormInfo : IReference + { + private int m_SerialId; + private UIGroup m_UIGroup; + private bool m_PauseCoveredUIForm; + private object m_UserData; + + public OpenUIFormInfo() + { + m_SerialId = 0; + m_UIGroup = null; + m_PauseCoveredUIForm = false; + m_UserData = null; + } + + public int SerialId + { + get + { + return m_SerialId; + } + } + + public UIGroup UIGroup + { + get + { + return m_UIGroup; + } + } + + public bool PauseCoveredUIForm + { + get + { + return m_PauseCoveredUIForm; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + + public static OpenUIFormInfo Create(int serialId, UIGroup uiGroup, bool pauseCoveredUIForm, object userData) + { + OpenUIFormInfo openUIFormInfo = ReferencePool.Acquire(); + openUIFormInfo.m_SerialId = serialId; + openUIFormInfo.m_UIGroup = uiGroup; + openUIFormInfo.m_PauseCoveredUIForm = pauseCoveredUIForm; + openUIFormInfo.m_UserData = userData; + return openUIFormInfo; + } + + public void Clear() + { + m_SerialId = 0; + m_UIGroup = null; + m_PauseCoveredUIForm = false; + m_UserData = null; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.OpenUIFormInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.OpenUIFormInfo.cs.meta new file mode 100644 index 0000000..1c7c7a7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.OpenUIFormInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 28687acea4a54464b8ca73baed244186 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIFormInstanceObject.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIFormInstanceObject.cs new file mode 100644 index 0000000..0436c88 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIFormInstanceObject.cs @@ -0,0 +1,60 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; + +namespace GameFramework.UI +{ + internal sealed partial class UIManager : GameFrameworkModule, IUIManager + { + /// + /// 界面实例对象。 + /// + private sealed class UIFormInstanceObject : ObjectBase + { + private object m_UIFormAsset; + private IUIFormHelper m_UIFormHelper; + + public UIFormInstanceObject() + { + m_UIFormAsset = null; + m_UIFormHelper = null; + } + + public static UIFormInstanceObject Create(string name, object uiFormAsset, object uiFormInstance, IUIFormHelper uiFormHelper) + { + if (uiFormAsset == null) + { + throw new GameFrameworkException("UI form asset is invalid."); + } + + if (uiFormHelper == null) + { + throw new GameFrameworkException("UI form helper is invalid."); + } + + UIFormInstanceObject uiFormInstanceObject = ReferencePool.Acquire(); + uiFormInstanceObject.Initialize(name, uiFormInstance); + uiFormInstanceObject.m_UIFormAsset = uiFormAsset; + uiFormInstanceObject.m_UIFormHelper = uiFormHelper; + return uiFormInstanceObject; + } + + public override void Clear() + { + base.Clear(); + m_UIFormAsset = null; + m_UIFormHelper = null; + } + + protected internal override void Release(bool isShutdown) + { + m_UIFormHelper.ReleaseUIForm(m_UIFormAsset, Target); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIFormInstanceObject.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIFormInstanceObject.cs.meta new file mode 100644 index 0000000..03c7540 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIFormInstanceObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9456966fbe78ac042b77d6521bd95764 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.UIFormInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.UIFormInfo.cs new file mode 100644 index 0000000..939aa48 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.UIFormInfo.cs @@ -0,0 +1,85 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.UI +{ + internal sealed partial class UIManager : GameFrameworkModule, IUIManager + { + private sealed partial class UIGroup : IUIGroup + { + /// + /// 界面组界面信息。 + /// + private sealed class UIFormInfo : IReference + { + private IUIForm m_UIForm; + private bool m_Paused; + private bool m_Covered; + + public UIFormInfo() + { + m_UIForm = null; + m_Paused = false; + m_Covered = false; + } + + public IUIForm UIForm + { + get + { + return m_UIForm; + } + } + + public bool Paused + { + get + { + return m_Paused; + } + set + { + m_Paused = value; + } + } + + public bool Covered + { + get + { + return m_Covered; + } + set + { + m_Covered = value; + } + } + + public static UIFormInfo Create(IUIForm uiForm) + { + if (uiForm == null) + { + throw new GameFrameworkException("UI form is invalid."); + } + + UIFormInfo uiFormInfo = ReferencePool.Acquire(); + uiFormInfo.m_UIForm = uiForm; + uiFormInfo.m_Paused = true; + uiFormInfo.m_Covered = true; + return uiFormInfo; + } + + public void Clear() + { + m_UIForm = null; + m_Paused = false; + m_Covered = false; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.UIFormInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.UIFormInfo.cs.meta new file mode 100644 index 0000000..c886e9a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.UIFormInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a985f3b239b81f947976dbc151acf19f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.cs new file mode 100644 index 0000000..3dea351 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.cs @@ -0,0 +1,517 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace GameFramework.UI +{ + internal sealed partial class UIManager : GameFrameworkModule, IUIManager + { + /// + /// 界面组。 + /// + private sealed partial class UIGroup : IUIGroup + { + private readonly string m_Name; + private int m_Depth; + private bool m_Pause; + private readonly IUIGroupHelper m_UIGroupHelper; + private readonly GameFrameworkLinkedList m_UIFormInfos; + private LinkedListNode m_CachedNode; + + /// + /// 初始化界面组的新实例。 + /// + /// 界面组名称。 + /// 界面组深度。 + /// 界面组辅助器。 + public UIGroup(string name, int depth, IUIGroupHelper uiGroupHelper) + { + if (string.IsNullOrEmpty(name)) + { + throw new GameFrameworkException("UI group name is invalid."); + } + + if (uiGroupHelper == null) + { + throw new GameFrameworkException("UI group helper is invalid."); + } + + m_Name = name; + m_Pause = false; + m_UIGroupHelper = uiGroupHelper; + m_UIFormInfos = new GameFrameworkLinkedList(); + m_CachedNode = null; + Depth = depth; + } + + /// + /// 获取界面组名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取或设置界面组深度。 + /// + public int Depth + { + get + { + return m_Depth; + } + set + { + if (m_Depth == value) + { + return; + } + + m_Depth = value; + m_UIGroupHelper.SetDepth(m_Depth); + Refresh(); + } + } + + /// + /// 获取或设置界面组是否暂停。 + /// + public bool Pause + { + get + { + return m_Pause; + } + set + { + if (m_Pause == value) + { + return; + } + + m_Pause = value; + Refresh(); + } + } + + /// + /// 获取界面组中界面数量。 + /// + public int UIFormCount + { + get + { + return m_UIFormInfos.Count; + } + } + + /// + /// 获取当前界面。 + /// + public IUIForm CurrentUIForm + { + get + { + return m_UIFormInfos.First != null ? m_UIFormInfos.First.Value.UIForm : null; + } + } + + /// + /// 获取界面组辅助器。 + /// + public IUIGroupHelper Helper + { + get + { + return m_UIGroupHelper; + } + } + + /// + /// 界面组轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + LinkedListNode current = m_UIFormInfos.First; + while (current != null) + { + if (current.Value.Paused) + { + break; + } + + m_CachedNode = current.Next; + current.Value.UIForm.OnUpdate(elapseSeconds, realElapseSeconds); + current = m_CachedNode; + m_CachedNode = null; + } + } + + /// + /// 界面组中是否存在界面。 + /// + /// 界面序列编号。 + /// 界面组中是否存在界面。 + public bool HasUIForm(int serialId) + { + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + if (uiFormInfo.UIForm.SerialId == serialId) + { + return true; + } + } + + return false; + } + + /// + /// 界面组中是否存在界面。 + /// + /// 界面资源名称。 + /// 界面组中是否存在界面。 + public bool HasUIForm(string uiFormAssetName) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + if (uiFormInfo.UIForm.UIFormAssetName == uiFormAssetName) + { + return true; + } + } + + return false; + } + + /// + /// 从界面组中获取界面。 + /// + /// 界面序列编号。 + /// 要获取的界面。 + public IUIForm GetUIForm(int serialId) + { + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + if (uiFormInfo.UIForm.SerialId == serialId) + { + return uiFormInfo.UIForm; + } + } + + return null; + } + + /// + /// 从界面组中获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public IUIForm GetUIForm(string uiFormAssetName) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + if (uiFormInfo.UIForm.UIFormAssetName == uiFormAssetName) + { + return uiFormInfo.UIForm; + } + } + + return null; + } + + /// + /// 从界面组中获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public IUIForm[] GetUIForms(string uiFormAssetName) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + List results = new List(); + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + if (uiFormInfo.UIForm.UIFormAssetName == uiFormAssetName) + { + results.Add(uiFormInfo.UIForm); + } + } + + return results.ToArray(); + } + + /// + /// 从界面组中获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public void GetUIForms(string uiFormAssetName, List results) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + if (uiFormInfo.UIForm.UIFormAssetName == uiFormAssetName) + { + results.Add(uiFormInfo.UIForm); + } + } + } + + /// + /// 从界面组中获取所有界面。 + /// + /// 界面组中的所有界面。 + public IUIForm[] GetAllUIForms() + { + List results = new List(); + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + results.Add(uiFormInfo.UIForm); + } + + return results.ToArray(); + } + + /// + /// 从界面组中获取所有界面。 + /// + /// 界面组中的所有界面。 + public void GetAllUIForms(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + results.Add(uiFormInfo.UIForm); + } + } + + /// + /// 往界面组增加界面。 + /// + /// 要增加的界面。 + public void AddUIForm(IUIForm uiForm) + { + m_UIFormInfos.AddFirst(UIFormInfo.Create(uiForm)); + } + + /// + /// 从界面组移除界面。 + /// + /// 要移除的界面。 + public void RemoveUIForm(IUIForm uiForm) + { + UIFormInfo uiFormInfo = GetUIFormInfo(uiForm); + if (uiFormInfo == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find UI form info for serial id '{0}', UI form asset name is '{1}'.", uiForm.SerialId, uiForm.UIFormAssetName)); + } + + if (!uiFormInfo.Covered) + { + uiFormInfo.Covered = true; + uiForm.OnCover(); + } + + if (!uiFormInfo.Paused) + { + uiFormInfo.Paused = true; + uiForm.OnPause(); + } + + if (m_CachedNode != null && m_CachedNode.Value.UIForm == uiForm) + { + m_CachedNode = m_CachedNode.Next; + } + + if (!m_UIFormInfos.Remove(uiFormInfo)) + { + throw new GameFrameworkException(Utility.Text.Format("UI group '{0}' not exists specified UI form '[{1}]{2}'.", m_Name, uiForm.SerialId, uiForm.UIFormAssetName)); + } + + ReferencePool.Release(uiFormInfo); + } + + /// + /// 激活界面。 + /// + /// 要激活的界面。 + /// 用户自定义数据。 + public void RefocusUIForm(IUIForm uiForm, object userData) + { + UIFormInfo uiFormInfo = GetUIFormInfo(uiForm); + if (uiFormInfo == null) + { + throw new GameFrameworkException("Can not find UI form info."); + } + + m_UIFormInfos.Remove(uiFormInfo); + m_UIFormInfos.AddFirst(uiFormInfo); + } + + /// + /// 刷新界面组。 + /// + public void Refresh() + { + LinkedListNode current = m_UIFormInfos.First; + bool pause = m_Pause; + bool cover = false; + int depth = UIFormCount; + while (current != null && current.Value != null) + { + LinkedListNode next = current.Next; + current.Value.UIForm.OnDepthChanged(Depth, depth--); + if (current.Value == null) + { + return; + } + + if (pause) + { + if (!current.Value.Covered) + { + current.Value.Covered = true; + current.Value.UIForm.OnCover(); + if (current.Value == null) + { + return; + } + } + + if (!current.Value.Paused) + { + current.Value.Paused = true; + current.Value.UIForm.OnPause(); + if (current.Value == null) + { + return; + } + } + } + else + { + if (current.Value.Paused) + { + current.Value.Paused = false; + current.Value.UIForm.OnResume(); + if (current.Value == null) + { + return; + } + } + + if (current.Value.UIForm.PauseCoveredUIForm) + { + pause = true; + } + + if (cover) + { + if (!current.Value.Covered) + { + current.Value.Covered = true; + current.Value.UIForm.OnCover(); + if (current.Value == null) + { + return; + } + } + } + else + { + if (current.Value.Covered) + { + current.Value.Covered = false; + current.Value.UIForm.OnReveal(); + if (current.Value == null) + { + return; + } + } + + cover = true; + } + } + + current = next; + } + } + + internal void InternalGetUIForms(string uiFormAssetName, List results) + { + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + if (uiFormInfo.UIForm.UIFormAssetName == uiFormAssetName) + { + results.Add(uiFormInfo.UIForm); + } + } + } + + internal void InternalGetAllUIForms(List results) + { + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + results.Add(uiFormInfo.UIForm); + } + } + + private UIFormInfo GetUIFormInfo(IUIForm uiForm) + { + if (uiForm == null) + { + throw new GameFrameworkException("UI form is invalid."); + } + + foreach (UIFormInfo uiFormInfo in m_UIFormInfos) + { + if (uiFormInfo.UIForm == uiForm) + { + return uiFormInfo; + } + } + + return null; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.cs.meta new file mode 100644 index 0000000..55c39db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.UIGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32bd5e9b8ec175c49b05b152d21cf9bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.cs new file mode 100644 index 0000000..05dc87e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.cs @@ -0,0 +1,1059 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.ObjectPool; +using GameFramework.Resource; +using System; +using System.Collections.Generic; + +namespace GameFramework.UI +{ + /// + /// 界面管理器。 + /// + internal sealed partial class UIManager : GameFrameworkModule, IUIManager + { + private readonly Dictionary m_UIGroups; + private readonly Dictionary m_UIFormsBeingLoaded; + private readonly HashSet m_UIFormsToReleaseOnLoad; + private readonly Queue m_RecycleQueue; + private readonly LoadAssetCallbacks m_LoadAssetCallbacks; + private IObjectPoolManager m_ObjectPoolManager; + private IResourceManager m_ResourceManager; + private IObjectPool m_InstancePool; + private IUIFormHelper m_UIFormHelper; + private int m_Serial; + private bool m_IsShutdown; + private EventHandler m_OpenUIFormSuccessEventHandler; + private EventHandler m_OpenUIFormFailureEventHandler; + private EventHandler m_OpenUIFormUpdateEventHandler; + private EventHandler m_OpenUIFormDependencyAssetEventHandler; + private EventHandler m_CloseUIFormCompleteEventHandler; + + /// + /// 初始化界面管理器的新实例。 + /// + public UIManager() + { + m_UIGroups = new Dictionary(StringComparer.Ordinal); + m_UIFormsBeingLoaded = new Dictionary(); + m_UIFormsToReleaseOnLoad = new HashSet(); + m_RecycleQueue = new Queue(); + m_LoadAssetCallbacks = new LoadAssetCallbacks(LoadAssetSuccessCallback, LoadAssetFailureCallback, LoadAssetUpdateCallback, LoadAssetDependencyAssetCallback); + m_ObjectPoolManager = null; + m_ResourceManager = null; + m_InstancePool = null; + m_UIFormHelper = null; + m_Serial = 0; + m_IsShutdown = false; + m_OpenUIFormSuccessEventHandler = null; + m_OpenUIFormFailureEventHandler = null; + m_OpenUIFormUpdateEventHandler = null; + m_OpenUIFormDependencyAssetEventHandler = null; + m_CloseUIFormCompleteEventHandler = null; + } + + /// + /// 获取界面组数量。 + /// + public int UIGroupCount + { + get + { + return m_UIGroups.Count; + } + } + + /// + /// 获取或设置界面实例对象池自动释放可释放对象的间隔秒数。 + /// + public float InstanceAutoReleaseInterval + { + get + { + return m_InstancePool.AutoReleaseInterval; + } + set + { + m_InstancePool.AutoReleaseInterval = value; + } + } + + /// + /// 获取或设置界面实例对象池的容量。 + /// + public int InstanceCapacity + { + get + { + return m_InstancePool.Capacity; + } + set + { + m_InstancePool.Capacity = value; + } + } + + /// + /// 获取或设置界面实例对象池对象过期秒数。 + /// + public float InstanceExpireTime + { + get + { + return m_InstancePool.ExpireTime; + } + set + { + m_InstancePool.ExpireTime = value; + } + } + + /// + /// 获取或设置界面实例对象池的优先级。 + /// + public int InstancePriority + { + get + { + return m_InstancePool.Priority; + } + set + { + m_InstancePool.Priority = value; + } + } + + /// + /// 打开界面成功事件。 + /// + public event EventHandler OpenUIFormSuccess + { + add + { + m_OpenUIFormSuccessEventHandler += value; + } + remove + { + m_OpenUIFormSuccessEventHandler -= value; + } + } + + /// + /// 打开界面失败事件。 + /// + public event EventHandler OpenUIFormFailure + { + add + { + m_OpenUIFormFailureEventHandler += value; + } + remove + { + m_OpenUIFormFailureEventHandler -= value; + } + } + + /// + /// 打开界面更新事件。 + /// + public event EventHandler OpenUIFormUpdate + { + add + { + m_OpenUIFormUpdateEventHandler += value; + } + remove + { + m_OpenUIFormUpdateEventHandler -= value; + } + } + + /// + /// 打开界面时加载依赖资源事件。 + /// + public event EventHandler OpenUIFormDependencyAsset + { + add + { + m_OpenUIFormDependencyAssetEventHandler += value; + } + remove + { + m_OpenUIFormDependencyAssetEventHandler -= value; + } + } + + /// + /// 关闭界面完成事件。 + /// + public event EventHandler CloseUIFormComplete + { + add + { + m_CloseUIFormCompleteEventHandler += value; + } + remove + { + m_CloseUIFormCompleteEventHandler -= value; + } + } + + /// + /// 界面管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + while (m_RecycleQueue.Count > 0) + { + IUIForm uiForm = m_RecycleQueue.Dequeue(); + uiForm.OnRecycle(); + m_InstancePool.Unspawn(uiForm.Handle); + } + + foreach (KeyValuePair uiGroup in m_UIGroups) + { + uiGroup.Value.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理界面管理器。 + /// + internal override void Shutdown() + { + m_IsShutdown = true; + CloseAllLoadedUIForms(); + m_UIGroups.Clear(); + m_UIFormsBeingLoaded.Clear(); + m_UIFormsToReleaseOnLoad.Clear(); + m_RecycleQueue.Clear(); + } + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + public void SetObjectPoolManager(IObjectPoolManager objectPoolManager) + { + if (objectPoolManager == null) + { + throw new GameFrameworkException("Object pool manager is invalid."); + } + + m_ObjectPoolManager = objectPoolManager; + m_InstancePool = m_ObjectPoolManager.CreateSingleSpawnObjectPool("UI Instance Pool"); + } + + /// + /// 设置资源管理器。 + /// + /// 资源管理器。 + public void SetResourceManager(IResourceManager resourceManager) + { + if (resourceManager == null) + { + throw new GameFrameworkException("Resource manager is invalid."); + } + + m_ResourceManager = resourceManager; + } + + /// + /// 设置界面辅助器。 + /// + /// 界面辅助器。 + public void SetUIFormHelper(IUIFormHelper uiFormHelper) + { + if (uiFormHelper == null) + { + throw new GameFrameworkException("UI form helper is invalid."); + } + + m_UIFormHelper = uiFormHelper; + } + + /// + /// 是否存在界面组。 + /// + /// 界面组名称。 + /// 是否存在界面组。 + public bool HasUIGroup(string uiGroupName) + { + if (string.IsNullOrEmpty(uiGroupName)) + { + throw new GameFrameworkException("UI group name is invalid."); + } + + return m_UIGroups.ContainsKey(uiGroupName); + } + + /// + /// 获取界面组。 + /// + /// 界面组名称。 + /// 要获取的界面组。 + public IUIGroup GetUIGroup(string uiGroupName) + { + if (string.IsNullOrEmpty(uiGroupName)) + { + throw new GameFrameworkException("UI group name is invalid."); + } + + UIGroup uiGroup = null; + if (m_UIGroups.TryGetValue(uiGroupName, out uiGroup)) + { + return uiGroup; + } + + return null; + } + + /// + /// 获取所有界面组。 + /// + /// 所有界面组。 + public IUIGroup[] GetAllUIGroups() + { + int index = 0; + IUIGroup[] results = new IUIGroup[m_UIGroups.Count]; + foreach (KeyValuePair uiGroup in m_UIGroups) + { + results[index++] = uiGroup.Value; + } + + return results; + } + + /// + /// 获取所有界面组。 + /// + /// 所有界面组。 + public void GetAllUIGroups(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair uiGroup in m_UIGroups) + { + results.Add(uiGroup.Value); + } + } + + /// + /// 增加界面组。 + /// + /// 界面组名称。 + /// 界面组辅助器。 + /// 是否增加界面组成功。 + public bool AddUIGroup(string uiGroupName, IUIGroupHelper uiGroupHelper) + { + return AddUIGroup(uiGroupName, 0, uiGroupHelper); + } + + /// + /// 增加界面组。 + /// + /// 界面组名称。 + /// 界面组深度。 + /// 界面组辅助器。 + /// 是否增加界面组成功。 + public bool AddUIGroup(string uiGroupName, int uiGroupDepth, IUIGroupHelper uiGroupHelper) + { + if (string.IsNullOrEmpty(uiGroupName)) + { + throw new GameFrameworkException("UI group name is invalid."); + } + + if (uiGroupHelper == null) + { + throw new GameFrameworkException("UI group helper is invalid."); + } + + if (HasUIGroup(uiGroupName)) + { + return false; + } + + m_UIGroups.Add(uiGroupName, new UIGroup(uiGroupName, uiGroupDepth, uiGroupHelper)); + + return true; + } + + /// + /// 是否存在界面。 + /// + /// 界面序列编号。 + /// 是否存在界面。 + public bool HasUIForm(int serialId) + { + foreach (KeyValuePair uiGroup in m_UIGroups) + { + if (uiGroup.Value.HasUIForm(serialId)) + { + return true; + } + } + + return false; + } + + /// + /// 是否存在界面。 + /// + /// 界面资源名称。 + /// 是否存在界面。 + public bool HasUIForm(string uiFormAssetName) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + foreach (KeyValuePair uiGroup in m_UIGroups) + { + if (uiGroup.Value.HasUIForm(uiFormAssetName)) + { + return true; + } + } + + return false; + } + + /// + /// 获取界面。 + /// + /// 界面序列编号。 + /// 要获取的界面。 + public IUIForm GetUIForm(int serialId) + { + foreach (KeyValuePair uiGroup in m_UIGroups) + { + IUIForm uiForm = uiGroup.Value.GetUIForm(serialId); + if (uiForm != null) + { + return uiForm; + } + } + + return null; + } + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public IUIForm GetUIForm(string uiFormAssetName) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + foreach (KeyValuePair uiGroup in m_UIGroups) + { + IUIForm uiForm = uiGroup.Value.GetUIForm(uiFormAssetName); + if (uiForm != null) + { + return uiForm; + } + } + + return null; + } + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public IUIForm[] GetUIForms(string uiFormAssetName) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + List results = new List(); + foreach (KeyValuePair uiGroup in m_UIGroups) + { + results.AddRange(uiGroup.Value.GetUIForms(uiFormAssetName)); + } + + return results.ToArray(); + } + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public void GetUIForms(string uiFormAssetName, List results) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair uiGroup in m_UIGroups) + { + uiGroup.Value.InternalGetUIForms(uiFormAssetName, results); + } + } + + /// + /// 获取所有已加载的界面。 + /// + /// 所有已加载的界面。 + public IUIForm[] GetAllLoadedUIForms() + { + List results = new List(); + foreach (KeyValuePair uiGroup in m_UIGroups) + { + results.AddRange(uiGroup.Value.GetAllUIForms()); + } + + return results.ToArray(); + } + + /// + /// 获取所有已加载的界面。 + /// + /// 所有已加载的界面。 + public void GetAllLoadedUIForms(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair uiGroup in m_UIGroups) + { + uiGroup.Value.InternalGetAllUIForms(results); + } + } + + /// + /// 获取所有正在加载界面的序列编号。 + /// + /// 所有正在加载界面的序列编号。 + public int[] GetAllLoadingUIFormSerialIds() + { + int index = 0; + int[] results = new int[m_UIFormsBeingLoaded.Count]; + foreach (KeyValuePair uiFormBeingLoaded in m_UIFormsBeingLoaded) + { + results[index++] = uiFormBeingLoaded.Key; + } + + return results; + } + + /// + /// 获取所有正在加载界面的序列编号。 + /// + /// 所有正在加载界面的序列编号。 + public void GetAllLoadingUIFormSerialIds(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair uiFormBeingLoaded in m_UIFormsBeingLoaded) + { + results.Add(uiFormBeingLoaded.Key); + } + } + + /// + /// 是否正在加载界面。 + /// + /// 界面序列编号。 + /// 是否正在加载界面。 + public bool IsLoadingUIForm(int serialId) + { + return m_UIFormsBeingLoaded.ContainsKey(serialId); + } + + /// + /// 是否正在加载界面。 + /// + /// 界面资源名称。 + /// 是否正在加载界面。 + public bool IsLoadingUIForm(string uiFormAssetName) + { + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + return m_UIFormsBeingLoaded.ContainsValue(uiFormAssetName); + } + + /// + /// 是否是合法的界面。 + /// + /// 界面。 + /// 界面是否合法。 + public bool IsValidUIForm(IUIForm uiForm) + { + if (uiForm == null) + { + return false; + } + + return HasUIForm(uiForm.SerialId); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName) + { + return OpenUIForm(uiFormAssetName, uiGroupName, Constant.DefaultPriority, false, null); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority) + { + return OpenUIForm(uiFormAssetName, uiGroupName, priority, false, null); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm) + { + return OpenUIForm(uiFormAssetName, uiGroupName, Constant.DefaultPriority, pauseCoveredUIForm, null); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 用户自定义数据。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, object userData) + { + return OpenUIForm(uiFormAssetName, uiGroupName, Constant.DefaultPriority, false, userData); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 是否暂停被覆盖的界面。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm) + { + return OpenUIForm(uiFormAssetName, uiGroupName, priority, pauseCoveredUIForm, null); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 用户自定义数据。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, object userData) + { + return OpenUIForm(uiFormAssetName, uiGroupName, priority, false, userData); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 用户自定义数据。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm, object userData) + { + return OpenUIForm(uiFormAssetName, uiGroupName, Constant.DefaultPriority, pauseCoveredUIForm, userData); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 是否暂停被覆盖的界面。 + /// 用户自定义数据。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm, object userData) + { + if (m_ResourceManager == null) + { + throw new GameFrameworkException("You must set resource manager first."); + } + + if (m_UIFormHelper == null) + { + throw new GameFrameworkException("You must set UI form helper first."); + } + + if (string.IsNullOrEmpty(uiFormAssetName)) + { + throw new GameFrameworkException("UI form asset name is invalid."); + } + + if (string.IsNullOrEmpty(uiGroupName)) + { + throw new GameFrameworkException("UI group name is invalid."); + } + + UIGroup uiGroup = (UIGroup)GetUIGroup(uiGroupName); + if (uiGroup == null) + { + throw new GameFrameworkException(Utility.Text.Format("UI group '{0}' is not exist.", uiGroupName)); + } + + int serialId = ++m_Serial; + UIFormInstanceObject uiFormInstanceObject = m_InstancePool.Spawn(uiFormAssetName); + if (uiFormInstanceObject == null) + { + m_UIFormsBeingLoaded.Add(serialId, uiFormAssetName); + m_ResourceManager.LoadAsset(uiFormAssetName, priority, m_LoadAssetCallbacks, OpenUIFormInfo.Create(serialId, uiGroup, pauseCoveredUIForm, userData)); + } + else + { + InternalOpenUIForm(serialId, uiFormAssetName, uiGroup, uiFormInstanceObject.Target, pauseCoveredUIForm, false, 0f, userData); + } + + return serialId; + } + + /// + /// 关闭界面。 + /// + /// 要关闭界面的序列编号。 + public void CloseUIForm(int serialId) + { + CloseUIForm(serialId, null); + } + + /// + /// 关闭界面。 + /// + /// 要关闭界面的序列编号。 + /// 用户自定义数据。 + public void CloseUIForm(int serialId, object userData) + { + if (IsLoadingUIForm(serialId)) + { + m_UIFormsToReleaseOnLoad.Add(serialId); + m_UIFormsBeingLoaded.Remove(serialId); + return; + } + + IUIForm uiForm = GetUIForm(serialId); + if (uiForm == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find UI form '{0}'.", serialId)); + } + + CloseUIForm(uiForm, userData); + } + + /// + /// 关闭界面。 + /// + /// 要关闭的界面。 + public void CloseUIForm(IUIForm uiForm) + { + CloseUIForm(uiForm, null); + } + + /// + /// 关闭界面。 + /// + /// 要关闭的界面。 + /// 用户自定义数据。 + public void CloseUIForm(IUIForm uiForm, object userData) + { + if (uiForm == null) + { + throw new GameFrameworkException("UI form is invalid."); + } + + UIGroup uiGroup = (UIGroup)uiForm.UIGroup; + if (uiGroup == null) + { + throw new GameFrameworkException("UI group is invalid."); + } + + uiGroup.RemoveUIForm(uiForm); + uiForm.OnClose(m_IsShutdown, userData); + uiGroup.Refresh(); + + if (m_CloseUIFormCompleteEventHandler != null) + { + CloseUIFormCompleteEventArgs closeUIFormCompleteEventArgs = CloseUIFormCompleteEventArgs.Create(uiForm.SerialId, uiForm.UIFormAssetName, uiGroup, userData); + m_CloseUIFormCompleteEventHandler(this, closeUIFormCompleteEventArgs); + ReferencePool.Release(closeUIFormCompleteEventArgs); + } + + m_RecycleQueue.Enqueue(uiForm); + } + + /// + /// 关闭所有已加载的界面。 + /// + public void CloseAllLoadedUIForms() + { + CloseAllLoadedUIForms(null); + } + + /// + /// 关闭所有已加载的界面。 + /// + /// 用户自定义数据。 + public void CloseAllLoadedUIForms(object userData) + { + IUIForm[] uiForms = GetAllLoadedUIForms(); + foreach (IUIForm uiForm in uiForms) + { + if (!HasUIForm(uiForm.SerialId)) + { + continue; + } + + CloseUIForm(uiForm, userData); + } + } + + /// + /// 关闭所有正在加载的界面。 + /// + public void CloseAllLoadingUIForms() + { + foreach (KeyValuePair uiFormBeingLoaded in m_UIFormsBeingLoaded) + { + m_UIFormsToReleaseOnLoad.Add(uiFormBeingLoaded.Key); + } + + m_UIFormsBeingLoaded.Clear(); + } + + /// + /// 激活界面。 + /// + /// 要激活的界面。 + public void RefocusUIForm(IUIForm uiForm) + { + RefocusUIForm(uiForm, null); + } + + /// + /// 激活界面。 + /// + /// 要激活的界面。 + /// 用户自定义数据。 + public void RefocusUIForm(IUIForm uiForm, object userData) + { + if (uiForm == null) + { + throw new GameFrameworkException("UI form is invalid."); + } + + UIGroup uiGroup = (UIGroup)uiForm.UIGroup; + if (uiGroup == null) + { + throw new GameFrameworkException("UI group is invalid."); + } + + uiGroup.RefocusUIForm(uiForm, userData); + uiGroup.Refresh(); + uiForm.OnRefocus(userData); + } + + /// + /// 设置界面实例是否被加锁。 + /// + /// 要设置是否被加锁的界面实例。 + /// 界面实例是否被加锁。 + public void SetUIFormInstanceLocked(object uiFormInstance, bool locked) + { + if (uiFormInstance == null) + { + throw new GameFrameworkException("UI form instance is invalid."); + } + + m_InstancePool.SetLocked(uiFormInstance, locked); + } + + /// + /// 设置界面实例的优先级。 + /// + /// 要设置优先级的界面实例。 + /// 界面实例优先级。 + public void SetUIFormInstancePriority(object uiFormInstance, int priority) + { + if (uiFormInstance == null) + { + throw new GameFrameworkException("UI form instance is invalid."); + } + + m_InstancePool.SetPriority(uiFormInstance, priority); + } + + private void InternalOpenUIForm(int serialId, string uiFormAssetName, UIGroup uiGroup, object uiFormInstance, bool pauseCoveredUIForm, bool isNewInstance, float duration, object userData) + { + try + { + IUIForm uiForm = m_UIFormHelper.CreateUIForm(uiFormInstance, uiGroup, userData); + if (uiForm == null) + { + throw new GameFrameworkException("Can not create UI form in UI form helper."); + } + + uiForm.OnInit(serialId, uiFormAssetName, uiGroup, pauseCoveredUIForm, isNewInstance, userData); + uiGroup.AddUIForm(uiForm); + uiForm.OnOpen(userData); + uiGroup.Refresh(); + + if (m_OpenUIFormSuccessEventHandler != null) + { + OpenUIFormSuccessEventArgs openUIFormSuccessEventArgs = OpenUIFormSuccessEventArgs.Create(uiForm, duration, userData); + m_OpenUIFormSuccessEventHandler(this, openUIFormSuccessEventArgs); + ReferencePool.Release(openUIFormSuccessEventArgs); + } + } + catch (Exception exception) + { + if (m_OpenUIFormFailureEventHandler != null) + { + OpenUIFormFailureEventArgs openUIFormFailureEventArgs = OpenUIFormFailureEventArgs.Create(serialId, uiFormAssetName, uiGroup.Name, pauseCoveredUIForm, exception.ToString(), userData); + m_OpenUIFormFailureEventHandler(this, openUIFormFailureEventArgs); + ReferencePool.Release(openUIFormFailureEventArgs); + return; + } + + throw; + } + } + + private void LoadAssetSuccessCallback(string uiFormAssetName, object uiFormAsset, float duration, object userData) + { + OpenUIFormInfo openUIFormInfo = (OpenUIFormInfo)userData; + if (openUIFormInfo == null) + { + throw new GameFrameworkException("Open UI form info is invalid."); + } + + if (m_UIFormsToReleaseOnLoad.Contains(openUIFormInfo.SerialId)) + { + m_UIFormsToReleaseOnLoad.Remove(openUIFormInfo.SerialId); + ReferencePool.Release(openUIFormInfo); + m_UIFormHelper.ReleaseUIForm(uiFormAsset, null); + return; + } + + m_UIFormsBeingLoaded.Remove(openUIFormInfo.SerialId); + UIFormInstanceObject uiFormInstanceObject = UIFormInstanceObject.Create(uiFormAssetName, uiFormAsset, m_UIFormHelper.InstantiateUIForm(uiFormAsset), m_UIFormHelper); + m_InstancePool.Register(uiFormInstanceObject, true); + + InternalOpenUIForm(openUIFormInfo.SerialId, uiFormAssetName, openUIFormInfo.UIGroup, uiFormInstanceObject.Target, openUIFormInfo.PauseCoveredUIForm, true, duration, openUIFormInfo.UserData); + ReferencePool.Release(openUIFormInfo); + } + + private void LoadAssetFailureCallback(string uiFormAssetName, LoadResourceStatus status, string errorMessage, object userData) + { + OpenUIFormInfo openUIFormInfo = (OpenUIFormInfo)userData; + if (openUIFormInfo == null) + { + throw new GameFrameworkException("Open UI form info is invalid."); + } + + if (m_UIFormsToReleaseOnLoad.Contains(openUIFormInfo.SerialId)) + { + m_UIFormsToReleaseOnLoad.Remove(openUIFormInfo.SerialId); + return; + } + + m_UIFormsBeingLoaded.Remove(openUIFormInfo.SerialId); + string appendErrorMessage = Utility.Text.Format("Load UI form failure, asset name '{0}', status '{1}', error message '{2}'.", uiFormAssetName, status, errorMessage); + if (m_OpenUIFormFailureEventHandler != null) + { + OpenUIFormFailureEventArgs openUIFormFailureEventArgs = OpenUIFormFailureEventArgs.Create(openUIFormInfo.SerialId, uiFormAssetName, openUIFormInfo.UIGroup.Name, openUIFormInfo.PauseCoveredUIForm, appendErrorMessage, openUIFormInfo.UserData); + m_OpenUIFormFailureEventHandler(this, openUIFormFailureEventArgs); + ReferencePool.Release(openUIFormFailureEventArgs); + return; + } + + throw new GameFrameworkException(appendErrorMessage); + } + + private void LoadAssetUpdateCallback(string uiFormAssetName, float progress, object userData) + { + OpenUIFormInfo openUIFormInfo = (OpenUIFormInfo)userData; + if (openUIFormInfo == null) + { + throw new GameFrameworkException("Open UI form info is invalid."); + } + + if (m_OpenUIFormUpdateEventHandler != null) + { + OpenUIFormUpdateEventArgs openUIFormUpdateEventArgs = OpenUIFormUpdateEventArgs.Create(openUIFormInfo.SerialId, uiFormAssetName, openUIFormInfo.UIGroup.Name, openUIFormInfo.PauseCoveredUIForm, progress, openUIFormInfo.UserData); + m_OpenUIFormUpdateEventHandler(this, openUIFormUpdateEventArgs); + ReferencePool.Release(openUIFormUpdateEventArgs); + } + } + + private void LoadAssetDependencyAssetCallback(string uiFormAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData) + { + OpenUIFormInfo openUIFormInfo = (OpenUIFormInfo)userData; + if (openUIFormInfo == null) + { + throw new GameFrameworkException("Open UI form info is invalid."); + } + + if (m_OpenUIFormDependencyAssetEventHandler != null) + { + OpenUIFormDependencyAssetEventArgs openUIFormDependencyAssetEventArgs = OpenUIFormDependencyAssetEventArgs.Create(openUIFormInfo.SerialId, uiFormAssetName, openUIFormInfo.UIGroup.Name, openUIFormInfo.PauseCoveredUIForm, dependencyAssetName, loadedCount, totalCount, openUIFormInfo.UserData); + m_OpenUIFormDependencyAssetEventHandler(this, openUIFormDependencyAssetEventArgs); + ReferencePool.Release(openUIFormDependencyAssetEventArgs); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.cs.meta new file mode 100644 index 0000000..ca26035 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/UI/UIManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 60cc85a690b85b949a77b27ba98a68d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility.meta new file mode 100644 index 0000000..63463d3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fda02aac454562249a337cbfa4d99e01 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Assembly.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Assembly.cs new file mode 100644 index 0000000..22143e4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Assembly.cs @@ -0,0 +1,109 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// 程序集相关的实用函数。 + /// + public static class Assembly + { + private static readonly System.Reflection.Assembly[] s_Assemblies = null; + private static readonly Dictionary s_CachedTypes = new Dictionary(StringComparer.Ordinal); + + static Assembly() + { + s_Assemblies = AppDomain.CurrentDomain.GetAssemblies(); + } + + /// + /// 获取已加载的程序集。 + /// + /// 已加载的程序集。 + public static System.Reflection.Assembly[] GetAssemblies() + { + return s_Assemblies; + } + + /// + /// 获取已加载的程序集中的所有类型。 + /// + /// 已加载的程序集中的所有类型。 + public static Type[] GetTypes() + { + List results = new List(); + foreach (System.Reflection.Assembly assembly in s_Assemblies) + { + results.AddRange(assembly.GetTypes()); + } + + return results.ToArray(); + } + + /// + /// 获取已加载的程序集中的所有类型。 + /// + /// 已加载的程序集中的所有类型。 + public static void GetTypes(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (System.Reflection.Assembly assembly in s_Assemblies) + { + results.AddRange(assembly.GetTypes()); + } + } + + /// + /// 获取已加载的程序集中的指定类型。 + /// + /// 要获取的类型名。 + /// 已加载的程序集中的指定类型。 + public static Type GetType(string typeName) + { + if (string.IsNullOrEmpty(typeName)) + { + throw new GameFrameworkException("Type name is invalid."); + } + + Type type = null; + if (s_CachedTypes.TryGetValue(typeName, out type)) + { + return type; + } + + type = Type.GetType(typeName); + if (type != null) + { + s_CachedTypes.Add(typeName, type); + return type; + } + + foreach (System.Reflection.Assembly assembly in s_Assemblies) + { + type = Type.GetType(Text.Format("{0}, {1}", typeName, assembly.FullName)); + if (type != null) + { + s_CachedTypes.Add(typeName, type); + return type; + } + } + + return null; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Assembly.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Assembly.cs.meta new file mode 100644 index 0000000..6311554 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Assembly.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9083ccb040eb9d5479195c1e3d54a408 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.ICompressionHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.ICompressionHelper.cs new file mode 100644 index 0000000..3ecda01 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.ICompressionHelper.cs @@ -0,0 +1,59 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.IO; + +namespace GameFramework +{ + public static partial class Utility + { + public static partial class Compression + { + /// + /// 压缩解压缩辅助器接口。 + /// + public interface ICompressionHelper + { + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 要压缩的数据的二进制流的偏移。 + /// 要压缩的数据的二进制流的长度。 + /// 压缩后的数据的二进制流。 + /// 是否压缩数据成功。 + bool Compress(byte[] bytes, int offset, int length, Stream compressedStream); + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 压缩后的数据的二进制流。 + /// 是否压缩数据成功。 + bool Compress(Stream stream, Stream compressedStream); + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 要解压缩的数据的二进制流的偏移。 + /// 要解压缩的数据的二进制流的长度。 + /// 解压缩后的数据的二进制流。 + /// 是否解压缩数据成功。 + bool Decompress(byte[] bytes, int offset, int length, Stream decompressedStream); + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 解压缩后的数据的二进制流。 + /// 是否解压缩数据成功。 + bool Decompress(Stream stream, Stream decompressedStream); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.ICompressionHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.ICompressionHelper.cs.meta new file mode 100644 index 0000000..44c21d6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.ICompressionHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 062b672ef8dbcc24ca054d8f890047aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.cs new file mode 100644 index 0000000..64a2840 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.cs @@ -0,0 +1,344 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.IO; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// 压缩解压缩相关的实用函数。 + /// + public static partial class Compression + { + private static ICompressionHelper s_CompressionHelper = null; + + /// + /// 设置压缩解压缩辅助器。 + /// + /// 要设置的压缩解压缩辅助器。 + public static void SetCompressionHelper(ICompressionHelper compressionHelper) + { + s_CompressionHelper = compressionHelper; + } + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 压缩后的数据的二进制流。 + public static byte[] Compress(byte[] bytes) + { + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + return Compress(bytes, 0, bytes.Length); + } + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 压缩后的数据的二进制流。 + /// 是否压缩数据成功。 + public static bool Compress(byte[] bytes, Stream compressedStream) + { + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + return Compress(bytes, 0, bytes.Length, compressedStream); + } + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 要压缩的数据的二进制流的偏移。 + /// 要压缩的数据的二进制流的长度。 + /// 压缩后的数据的二进制流。 + public static byte[] Compress(byte[] bytes, int offset, int length) + { + using (MemoryStream compressedStream = new MemoryStream()) + { + if (Compress(bytes, offset, length, compressedStream)) + { + return compressedStream.ToArray(); + } + else + { + return null; + } + } + } + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 要压缩的数据的二进制流的偏移。 + /// 要压缩的数据的二进制流的长度。 + /// 压缩后的数据的二进制流。 + /// 是否压缩数据成功。 + public static bool Compress(byte[] bytes, int offset, int length, Stream compressedStream) + { + if (s_CompressionHelper == null) + { + throw new GameFrameworkException("Compressed helper is invalid."); + } + + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + if (offset < 0 || length < 0 || offset + length > bytes.Length) + { + throw new GameFrameworkException("Offset or length is invalid."); + } + + if (compressedStream == null) + { + throw new GameFrameworkException("Compressed stream is invalid."); + } + + try + { + return s_CompressionHelper.Compress(bytes, offset, length, compressedStream); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Text.Format("Can not compress with exception '{0}'.", exception), exception); + } + } + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 压缩后的数据的二进制流。 + public static byte[] Compress(Stream stream) + { + using (MemoryStream compressedStream = new MemoryStream()) + { + if (Compress(stream, compressedStream)) + { + return compressedStream.ToArray(); + } + else + { + return null; + } + } + } + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 压缩后的数据的二进制流。 + /// 是否压缩数据成功。 + public static bool Compress(Stream stream, Stream compressedStream) + { + if (s_CompressionHelper == null) + { + throw new GameFrameworkException("Compressed helper is invalid."); + } + + if (stream == null) + { + throw new GameFrameworkException("Stream is invalid."); + } + + if (compressedStream == null) + { + throw new GameFrameworkException("Compressed stream is invalid."); + } + + try + { + return s_CompressionHelper.Compress(stream, compressedStream); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Text.Format("Can not compress with exception '{0}'.", exception), exception); + } + } + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 解压缩后的数据的二进制流。 + public static byte[] Decompress(byte[] bytes) + { + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + return Decompress(bytes, 0, bytes.Length); + } + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 解压缩后的数据的二进制流。 + /// 是否解压缩数据成功。 + public static bool Decompress(byte[] bytes, Stream decompressedStream) + { + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + return Decompress(bytes, 0, bytes.Length, decompressedStream); + } + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 要解压缩的数据的二进制流的偏移。 + /// 要解压缩的数据的二进制流的长度。 + /// 解压缩后的数据的二进制流。 + public static byte[] Decompress(byte[] bytes, int offset, int length) + { + using (MemoryStream decompressedStream = new MemoryStream()) + { + if (Decompress(bytes, offset, length, decompressedStream)) + { + return decompressedStream.ToArray(); + } + else + { + return null; + } + } + } + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 要解压缩的数据的二进制流的偏移。 + /// 要解压缩的数据的二进制流的长度。 + /// 解压缩后的数据的二进制流。 + /// 是否解压缩数据成功。 + public static bool Decompress(byte[] bytes, int offset, int length, Stream decompressedStream) + { + if (s_CompressionHelper == null) + { + throw new GameFrameworkException("Compressed helper is invalid."); + } + + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + if (offset < 0 || length < 0 || offset + length > bytes.Length) + { + throw new GameFrameworkException("Offset or length is invalid."); + } + + if (decompressedStream == null) + { + throw new GameFrameworkException("Decompressed stream is invalid."); + } + + try + { + return s_CompressionHelper.Decompress(bytes, offset, length, decompressedStream); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Text.Format("Can not decompress with exception '{0}'.", exception), exception); + } + } + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 是否解压缩数据成功。 + public static byte[] Decompress(Stream stream) + { + using (MemoryStream decompressedStream = new MemoryStream()) + { + if (Decompress(stream, decompressedStream)) + { + return decompressedStream.ToArray(); + } + else + { + return null; + } + } + } + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 解压缩后的数据的二进制流。 + /// 是否解压缩数据成功。 + public static bool Decompress(Stream stream, Stream decompressedStream) + { + if (s_CompressionHelper == null) + { + throw new GameFrameworkException("Compressed helper is invalid."); + } + + if (stream == null) + { + throw new GameFrameworkException("Stream is invalid."); + } + + if (decompressedStream == null) + { + throw new GameFrameworkException("Decompressed stream is invalid."); + } + + try + { + return s_CompressionHelper.Decompress(stream, decompressedStream); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Text.Format("Can not decompress with exception '{0}'.", exception), exception); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.cs.meta new file mode 100644 index 0000000..5b9b9ec --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Compression.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8f137320b778cb4aa7b0521aeb6d88c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Converter.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Converter.cs new file mode 100644 index 0000000..ba750b1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Converter.cs @@ -0,0 +1,848 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Text; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// 类型转换相关的实用函数。 + /// + public static class Converter + { + private const float InchesToCentimeters = 2.54f; // 1 inch = 2.54 cm + private const float CentimetersToInches = 1f / InchesToCentimeters; // 1 cm = 0.3937 inches + + /// + /// 获取数据在此计算机结构中存储时的字节顺序。 + /// + public static bool IsLittleEndian + { + get + { + return BitConverter.IsLittleEndian; + } + } + + /// + /// 获取或设置屏幕每英寸点数。 + /// + public static float ScreenDpi + { + get; + set; + } + + /// + /// 将像素转换为厘米。 + /// + /// 像素。 + /// 厘米。 + public static float GetCentimetersFromPixels(float pixels) + { + if (ScreenDpi <= 0) + { + throw new GameFrameworkException("You must set screen DPI first."); + } + + return InchesToCentimeters * pixels / ScreenDpi; + } + + /// + /// 将厘米转换为像素。 + /// + /// 厘米。 + /// 像素。 + public static float GetPixelsFromCentimeters(float centimeters) + { + if (ScreenDpi <= 0) + { + throw new GameFrameworkException("You must set screen DPI first."); + } + + return CentimetersToInches * centimeters * ScreenDpi; + } + + /// + /// 将像素转换为英寸。 + /// + /// 像素。 + /// 英寸。 + public static float GetInchesFromPixels(float pixels) + { + if (ScreenDpi <= 0) + { + throw new GameFrameworkException("You must set screen DPI first."); + } + + return pixels / ScreenDpi; + } + + /// + /// 将英寸转换为像素。 + /// + /// 英寸。 + /// 像素。 + public static float GetPixelsFromInches(float inches) + { + if (ScreenDpi <= 0) + { + throw new GameFrameworkException("You must set screen DPI first."); + } + + return inches * ScreenDpi; + } + + /// + /// 以字节数组的形式获取指定的布尔值。 + /// + /// 要转换的布尔值。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(bool value) + { + byte[] buffer = new byte[1]; + GetBytes(value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的布尔值。 + /// + /// 要转换的布尔值。 + /// 用于存放结果的字节数组。 + public static void GetBytes(bool value, byte[] buffer) + { + GetBytes(value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的布尔值。 + /// + /// 要转换的布尔值。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static void GetBytes(bool value, byte[] buffer, int startIndex) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + if (startIndex < 0 || startIndex + 1 > buffer.Length) + { + throw new GameFrameworkException("Start index is invalid."); + } + + buffer[startIndex] = value ? (byte)1 : (byte)0; + } + + /// + /// 返回由字节数组中首字节转换来的布尔值。 + /// + /// 字节数组。 + /// 如果 value 中的首字节非零,则为 true,否则为 false。 + public static bool GetBoolean(byte[] value) + { + return BitConverter.ToBoolean(value, 0); + } + + /// + /// 返回由字节数组中指定位置的一个字节转换来的布尔值。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 如果 value 中指定位置的字节非零,则为 true,否则为 false。 + public static bool GetBoolean(byte[] value, int startIndex) + { + return BitConverter.ToBoolean(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的 Unicode 字符值。 + /// + /// 要转换的字符。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(char value) + { + byte[] buffer = new byte[2]; + GetBytes((short)value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的 Unicode 字符值。 + /// + /// 要转换的字符。 + /// 用于存放结果的字节数组。 + public static void GetBytes(char value, byte[] buffer) + { + GetBytes((short)value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的 Unicode 字符值。 + /// + /// 要转换的字符。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static void GetBytes(char value, byte[] buffer, int startIndex) + { + GetBytes((short)value, buffer, startIndex); + } + + /// + /// 返回由字节数组中前两个字节转换来的 Unicode 字符。 + /// + /// 字节数组。 + /// 由两个字节构成的字符。 + public static char GetChar(byte[] value) + { + return BitConverter.ToChar(value, 0); + } + + /// + /// 返回由字节数组中指定位置的两个字节转换来的 Unicode 字符。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由两个字节构成的字符。 + public static char GetChar(byte[] value, int startIndex) + { + return BitConverter.ToChar(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的 16 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(short value) + { + byte[] buffer = new byte[2]; + GetBytes(value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的 16 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static void GetBytes(short value, byte[] buffer) + { + GetBytes(value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的 16 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static unsafe void GetBytes(short value, byte[] buffer, int startIndex) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + if (startIndex < 0 || startIndex + 2 > buffer.Length) + { + throw new GameFrameworkException("Start index is invalid."); + } + + fixed (byte* valueRef = buffer) + { + *(short*)(valueRef + startIndex) = value; + } + } + + /// + /// 返回由字节数组中前两个字节转换来的 16 位有符号整数。 + /// + /// 字节数组。 + /// 由两个字节构成的 16 位有符号整数。 + public static short GetInt16(byte[] value) + { + return BitConverter.ToInt16(value, 0); + } + + /// + /// 返回由字节数组中指定位置的两个字节转换来的 16 位有符号整数。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由两个字节构成的 16 位有符号整数。 + public static short GetInt16(byte[] value, int startIndex) + { + return BitConverter.ToInt16(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的 16 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(ushort value) + { + byte[] buffer = new byte[2]; + GetBytes((short)value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的 16 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static void GetBytes(ushort value, byte[] buffer) + { + GetBytes((short)value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的 16 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static void GetBytes(ushort value, byte[] buffer, int startIndex) + { + GetBytes((short)value, buffer, startIndex); + } + + /// + /// 返回由字节数组中前两个字节转换来的 16 位无符号整数。 + /// + /// 字节数组。 + /// 由两个字节构成的 16 位无符号整数。 + public static ushort GetUInt16(byte[] value) + { + return BitConverter.ToUInt16(value, 0); + } + + /// + /// 返回由字节数组中指定位置的两个字节转换来的 16 位无符号整数。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由两个字节构成的 16 位无符号整数。 + public static ushort GetUInt16(byte[] value, int startIndex) + { + return BitConverter.ToUInt16(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的 32 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(int value) + { + byte[] buffer = new byte[4]; + GetBytes(value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的 32 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static void GetBytes(int value, byte[] buffer) + { + GetBytes(value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的 32 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static unsafe void GetBytes(int value, byte[] buffer, int startIndex) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + if (startIndex < 0 || startIndex + 4 > buffer.Length) + { + throw new GameFrameworkException("Start index is invalid."); + } + + fixed (byte* valueRef = buffer) + { + *(int*)(valueRef + startIndex) = value; + } + } + + /// + /// 返回由字节数组中前四个字节转换来的 32 位有符号整数。 + /// + /// 字节数组。 + /// 由四个字节构成的 32 位有符号整数。 + public static int GetInt32(byte[] value) + { + return BitConverter.ToInt32(value, 0); + } + + /// + /// 返回由字节数组中指定位置的四个字节转换来的 32 位有符号整数。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由四个字节构成的 32 位有符号整数。 + public static int GetInt32(byte[] value, int startIndex) + { + return BitConverter.ToInt32(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的 32 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(uint value) + { + byte[] buffer = new byte[4]; + GetBytes((int)value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的 32 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static void GetBytes(uint value, byte[] buffer) + { + GetBytes((int)value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的 32 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static void GetBytes(uint value, byte[] buffer, int startIndex) + { + GetBytes((int)value, buffer, startIndex); + } + + /// + /// 返回由字节数组中前四个字节转换来的 32 位无符号整数。 + /// + /// 字节数组。 + /// 由四个字节构成的 32 位无符号整数。 + public static uint GetUInt32(byte[] value) + { + return BitConverter.ToUInt32(value, 0); + } + + /// + /// 返回由字节数组中指定位置的四个字节转换来的 32 位无符号整数。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由四个字节构成的 32 位无符号整数。 + public static uint GetUInt32(byte[] value, int startIndex) + { + return BitConverter.ToUInt32(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的 64 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(long value) + { + byte[] buffer = new byte[8]; + GetBytes(value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的 64 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static void GetBytes(long value, byte[] buffer) + { + GetBytes(value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的 64 位有符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static unsafe void GetBytes(long value, byte[] buffer, int startIndex) + { + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + if (startIndex < 0 || startIndex + 8 > buffer.Length) + { + throw new GameFrameworkException("Start index is invalid."); + } + + fixed (byte* valueRef = buffer) + { + *(long*)(valueRef + startIndex) = value; + } + } + + /// + /// 返回由字节数组中前八个字节转换来的 64 位有符号整数。 + /// + /// 字节数组。 + /// 由八个字节构成的 64 位有符号整数。 + public static long GetInt64(byte[] value) + { + return BitConverter.ToInt64(value, 0); + } + + /// + /// 返回由字节数组中指定位置的八个字节转换来的 64 位有符号整数。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由八个字节构成的 64 位有符号整数。 + public static long GetInt64(byte[] value, int startIndex) + { + return BitConverter.ToInt64(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的 64 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(ulong value) + { + byte[] buffer = new byte[8]; + GetBytes((long)value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的 64 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static void GetBytes(ulong value, byte[] buffer) + { + GetBytes((long)value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的 64 位无符号整数值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static void GetBytes(ulong value, byte[] buffer, int startIndex) + { + GetBytes((long)value, buffer, startIndex); + } + + /// + /// 返回由字节数组中前八个字节转换来的 64 位无符号整数。 + /// + /// 字节数组。 + /// 由八个字节构成的 64 位无符号整数。 + public static ulong GetUInt64(byte[] value) + { + return BitConverter.ToUInt64(value, 0); + } + + /// + /// 返回由字节数组中指定位置的八个字节转换来的 64 位无符号整数。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由八个字节构成的 64 位无符号整数。 + public static ulong GetUInt64(byte[] value, int startIndex) + { + return BitConverter.ToUInt64(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的单精度浮点值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static unsafe byte[] GetBytes(float value) + { + byte[] buffer = new byte[4]; + GetBytes(*(int*)&value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的单精度浮点值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static unsafe void GetBytes(float value, byte[] buffer) + { + GetBytes(*(int*)&value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的单精度浮点值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static unsafe void GetBytes(float value, byte[] buffer, int startIndex) + { + GetBytes(*(int*)&value, buffer, startIndex); + } + + /// + /// 返回由字节数组中前四个字节转换来的单精度浮点数。 + /// + /// 字节数组。 + /// 由四个字节构成的单精度浮点数。 + public static float GetSingle(byte[] value) + { + return BitConverter.ToSingle(value, 0); + } + + /// + /// 返回由字节数组中指定位置的四个字节转换来的单精度浮点数。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由四个字节构成的单精度浮点数。 + public static float GetSingle(byte[] value, int startIndex) + { + return BitConverter.ToSingle(value, startIndex); + } + + /// + /// 以字节数组的形式获取指定的双精度浮点值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static unsafe byte[] GetBytes(double value) + { + byte[] buffer = new byte[8]; + GetBytes(*(long*)&value, buffer, 0); + return buffer; + } + + /// + /// 以字节数组的形式获取指定的双精度浮点值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + public static unsafe void GetBytes(double value, byte[] buffer) + { + GetBytes(*(long*)&value, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定的双精度浮点值。 + /// + /// 要转换的数字。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + public static unsafe void GetBytes(double value, byte[] buffer, int startIndex) + { + GetBytes(*(long*)&value, buffer, startIndex); + } + + /// + /// 返回由字节数组中前八个字节转换来的双精度浮点数。 + /// + /// 字节数组。 + /// 由八个字节构成的双精度浮点数。 + public static double GetDouble(byte[] value) + { + return BitConverter.ToDouble(value, 0); + } + + /// + /// 返回由字节数组中指定位置的八个字节转换来的双精度浮点数。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 由八个字节构成的双精度浮点数。 + public static double GetDouble(byte[] value, int startIndex) + { + return BitConverter.ToDouble(value, startIndex); + } + + /// + /// 以字节数组的形式获取 UTF-8 编码的字符串。 + /// + /// 要转换的字符串。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(string value) + { + return GetBytes(value, Encoding.UTF8); + } + + /// + /// 以字节数组的形式获取 UTF-8 编码的字符串。 + /// + /// 要转换的字符串。 + /// 用于存放结果的字节数组。 + /// buffer 内实际填充了多少字节。 + public static int GetBytes(string value, byte[] buffer) + { + return GetBytes(value, Encoding.UTF8, buffer, 0); + } + + /// + /// 以字节数组的形式获取 UTF-8 编码的字符串。 + /// + /// 要转换的字符串。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + /// buffer 内实际填充了多少字节。 + public static int GetBytes(string value, byte[] buffer, int startIndex) + { + return GetBytes(value, Encoding.UTF8, buffer, startIndex); + } + + /// + /// 以字节数组的形式获取指定编码的字符串。 + /// + /// 要转换的字符串。 + /// 要使用的编码。 + /// 用于存放结果的字节数组。 + public static byte[] GetBytes(string value, Encoding encoding) + { + if (value == null) + { + throw new GameFrameworkException("Value is invalid."); + } + + if (encoding == null) + { + throw new GameFrameworkException("Encoding is invalid."); + } + + return encoding.GetBytes(value); + } + + /// + /// 以字节数组的形式获取指定编码的字符串。 + /// + /// 要转换的字符串。 + /// 要使用的编码。 + /// 用于存放结果的字节数组。 + /// buffer 内实际填充了多少字节。 + public static int GetBytes(string value, Encoding encoding, byte[] buffer) + { + return GetBytes(value, encoding, buffer, 0); + } + + /// + /// 以字节数组的形式获取指定编码的字符串。 + /// + /// 要转换的字符串。 + /// 要使用的编码。 + /// 用于存放结果的字节数组。 + /// buffer 内的起始位置。 + /// buffer 内实际填充了多少字节。 + public static int GetBytes(string value, Encoding encoding, byte[] buffer, int startIndex) + { + if (value == null) + { + throw new GameFrameworkException("Value is invalid."); + } + + if (encoding == null) + { + throw new GameFrameworkException("Encoding is invalid."); + } + + return encoding.GetBytes(value, 0, value.Length, buffer, startIndex); + } + + /// + /// 返回由字节数组使用 UTF-8 编码转换成的字符串。 + /// + /// 字节数组。 + /// 转换后的字符串。 + public static string GetString(byte[] value) + { + return GetString(value, Encoding.UTF8); + } + + /// + /// 返回由字节数组使用指定编码转换成的字符串。 + /// + /// 字节数组。 + /// 要使用的编码。 + /// 转换后的字符串。 + public static string GetString(byte[] value, Encoding encoding) + { + if (value == null) + { + throw new GameFrameworkException("Value is invalid."); + } + + if (encoding == null) + { + throw new GameFrameworkException("Encoding is invalid."); + } + + return encoding.GetString(value); + } + + /// + /// 返回由字节数组使用 UTF-8 编码转换成的字符串。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 长度。 + /// 转换后的字符串。 + public static string GetString(byte[] value, int startIndex, int length) + { + return GetString(value, startIndex, length, Encoding.UTF8); + } + + /// + /// 返回由字节数组使用指定编码转换成的字符串。 + /// + /// 字节数组。 + /// value 内的起始位置。 + /// 长度。 + /// 要使用的编码。 + /// 转换后的字符串。 + public static string GetString(byte[] value, int startIndex, int length, Encoding encoding) + { + if (value == null) + { + throw new GameFrameworkException("Value is invalid."); + } + + if (encoding == null) + { + throw new GameFrameworkException("Encoding is invalid."); + } + + return encoding.GetString(value, startIndex, length); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Converter.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Converter.cs.meta new file mode 100644 index 0000000..6498977 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Converter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad024314ea72bb34fa1477a414887b1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Encryption.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Encryption.cs new file mode 100644 index 0000000..ae40afc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Encryption.cs @@ -0,0 +1,134 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// 加密解密相关的实用函数。 + /// + public static class Encryption + { + internal const int QuickEncryptLength = 220; + + /// + /// 将 bytes 使用 code 做异或运算的快速版本。 + /// + /// 原始二进制流。 + /// 异或二进制流。 + /// 异或后的二进制流。 + public static byte[] GetQuickXorBytes(byte[] bytes, byte[] code) + { + return GetXorBytes(bytes, 0, QuickEncryptLength, code); + } + + /// + /// 将 bytes 使用 code 做异或运算的快速版本。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。 + /// + /// 原始及异或后的二进制流。 + /// 异或二进制流。 + public static void GetQuickSelfXorBytes(byte[] bytes, byte[] code) + { + GetSelfXorBytes(bytes, 0, QuickEncryptLength, code); + } + + /// + /// 将 bytes 使用 code 做异或运算。 + /// + /// 原始二进制流。 + /// 异或二进制流。 + /// 异或后的二进制流。 + public static byte[] GetXorBytes(byte[] bytes, byte[] code) + { + if (bytes == null) + { + return null; + } + + return GetXorBytes(bytes, 0, bytes.Length, code); + } + + /// + /// 将 bytes 使用 code 做异或运算。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。 + /// + /// 原始及异或后的二进制流。 + /// 异或二进制流。 + public static void GetSelfXorBytes(byte[] bytes, byte[] code) + { + if (bytes == null) + { + return; + } + + GetSelfXorBytes(bytes, 0, bytes.Length, code); + } + + /// + /// 将 bytes 使用 code 做异或运算。 + /// + /// 原始二进制流。 + /// 异或计算的开始位置。 + /// 异或计算长度,若小于 0,则计算整个二进制流。 + /// 异或二进制流。 + /// 异或后的二进制流。 + public static byte[] GetXorBytes(byte[] bytes, int startIndex, int length, byte[] code) + { + if (bytes == null) + { + return null; + } + + int bytesLength = bytes.Length; + byte[] results = new byte[bytesLength]; + Array.Copy(bytes, 0, results, 0, bytesLength); + GetSelfXorBytes(results, startIndex, length, code); + return results; + } + + /// + /// 将 bytes 使用 code 做异或运算。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。 + /// + /// 原始及异或后的二进制流。 + /// 异或计算的开始位置。 + /// 异或计算长度。 + /// 异或二进制流。 + public static void GetSelfXorBytes(byte[] bytes, int startIndex, int length, byte[] code) + { + if (bytes == null) + { + return; + } + + if (code == null) + { + throw new GameFrameworkException("Code is invalid."); + } + + int codeLength = code.Length; + if (codeLength <= 0) + { + throw new GameFrameworkException("Code length is invalid."); + } + + if (startIndex < 0 || length < 0 || startIndex + length > bytes.Length) + { + throw new GameFrameworkException("Start index or length is invalid."); + } + + int codeIndex = startIndex % codeLength; + for (int i = startIndex; i < length; i++) + { + bytes[i] ^= code[codeIndex++]; + codeIndex %= codeLength; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Encryption.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Encryption.cs.meta new file mode 100644 index 0000000..667c7fc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Encryption.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eaf16ba2a46cb9945bc28e37b6bf7da8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.IJsonHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.IJsonHelper.cs new file mode 100644 index 0000000..04e6385 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.IJsonHelper.cs @@ -0,0 +1,46 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + public static partial class Utility + { + public static partial class Json + { + /// + /// JSON 辅助器接口。 + /// + public interface IJsonHelper + { + /// + /// 将对象序列化为 JSON 字符串。 + /// + /// 要序列化的对象。 + /// 序列化后的 JSON 字符串。 + string ToJson(object obj); + + /// + /// 将 JSON 字符串反序列化为对象。 + /// + /// 对象类型。 + /// 要反序列化的 JSON 字符串。 + /// 反序列化后的对象。 + T ToObject(string json); + + /// + /// 将 JSON 字符串反序列化为对象。 + /// + /// 对象类型。 + /// 要反序列化的 JSON 字符串。 + /// 反序列化后的对象。 + object ToObject(Type objectType, string json); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.IJsonHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.IJsonHelper.cs.meta new file mode 100644 index 0000000..a9f0615 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.IJsonHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc8ca8ec9911cb84faa9f71b4fb651a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.cs new file mode 100644 index 0000000..d522db1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// JSON 相关的实用函数。 + /// + public static partial class Json + { + private static IJsonHelper s_JsonHelper = null; + + /// + /// 设置 JSON 辅助器。 + /// + /// 要设置的 JSON 辅助器。 + public static void SetJsonHelper(IJsonHelper jsonHelper) + { + s_JsonHelper = jsonHelper; + } + + /// + /// 将对象序列化为 JSON 字符串。 + /// + /// 要序列化的对象。 + /// 序列化后的 JSON 字符串。 + public static string ToJson(object obj) + { + if (s_JsonHelper == null) + { + throw new GameFrameworkException("JSON helper is invalid."); + } + + try + { + return s_JsonHelper.ToJson(obj); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Text.Format("Can not convert to JSON with exception '{0}'.", exception), exception); + } + } + + /// + /// 将 JSON 字符串反序列化为对象。 + /// + /// 对象类型。 + /// 要反序列化的 JSON 字符串。 + /// 反序列化后的对象。 + public static T ToObject(string json) + { + if (s_JsonHelper == null) + { + throw new GameFrameworkException("JSON helper is invalid."); + } + + try + { + return s_JsonHelper.ToObject(json); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Text.Format("Can not convert to object with exception '{0}'.", exception), exception); + } + } + + /// + /// 将 JSON 字符串反序列化为对象。 + /// + /// 对象类型。 + /// 要反序列化的 JSON 字符串。 + /// 反序列化后的对象。 + public static object ToObject(Type objectType, string json) + { + if (s_JsonHelper == null) + { + throw new GameFrameworkException("JSON helper is invalid."); + } + + if (objectType == null) + { + throw new GameFrameworkException("Object type is invalid."); + } + + try + { + return s_JsonHelper.ToObject(objectType, json); + } + catch (Exception exception) + { + if (exception is GameFrameworkException) + { + throw; + } + + throw new GameFrameworkException(Text.Format("Can not convert to object with exception '{0}'.", exception), exception); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.cs.meta new file mode 100644 index 0000000..7cf1265 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Json.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ccb42a278568d5444b1f52b1bdd798d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Marshal.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Marshal.cs new file mode 100644 index 0000000..9f238e7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Marshal.cs @@ -0,0 +1,240 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// Marshal 相关的实用函数。 + /// + public static class Marshal + { + private const int BlockSize = 1024 * 4; + private static IntPtr s_CachedHGlobalPtr = IntPtr.Zero; + private static int s_CachedHGlobalSize = 0; + + /// + /// 获取缓存的从进程的非托管内存中分配的内存的大小。 + /// + public static int CachedHGlobalSize + { + get + { + return s_CachedHGlobalSize; + } + } + + /// + /// 确保从进程的非托管内存中分配足够大小的内存并缓存。 + /// + /// 要确保从进程的非托管内存中分配内存的大小。 + public static void EnsureCachedHGlobalSize(int ensureSize) + { + if (ensureSize < 0) + { + throw new GameFrameworkException("Ensure size is invalid."); + } + + if (s_CachedHGlobalPtr == IntPtr.Zero || s_CachedHGlobalSize < ensureSize) + { + FreeCachedHGlobal(); + int size = (ensureSize - 1 + BlockSize) / BlockSize * BlockSize; + s_CachedHGlobalPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(size); + s_CachedHGlobalSize = size; + } + } + + /// + /// 释放缓存的从进程的非托管内存中分配的内存。 + /// + public static void FreeCachedHGlobal() + { + if (s_CachedHGlobalPtr != IntPtr.Zero) + { + System.Runtime.InteropServices.Marshal.FreeHGlobal(s_CachedHGlobalPtr); + s_CachedHGlobalPtr = IntPtr.Zero; + s_CachedHGlobalSize = 0; + } + } + + /// + /// 将数据从对象转换为二进制流。 + /// + /// 要转换的对象的类型。 + /// 要转换的对象。 + /// 存储转换结果的二进制流。 + public static byte[] StructureToBytes(T structure) + { + return StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T))); + } + + /// + /// 将数据从对象转换为二进制流。 + /// + /// 要转换的对象的类型。 + /// 要转换的对象。 + /// 要转换的对象的大小。 + /// 存储转换结果的二进制流。 + internal static byte[] StructureToBytes(T structure, int structureSize) + { + if (structureSize < 0) + { + throw new GameFrameworkException("Structure size is invalid."); + } + + EnsureCachedHGlobalSize(structureSize); + System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true); + byte[] result = new byte[structureSize]; + System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, 0, structureSize); + return result; + } + + /// + /// 将数据从对象转换为二进制流。 + /// + /// 要转换的对象的类型。 + /// 要转换的对象。 + /// 存储转换结果的二进制流。 + public static void StructureToBytes(T structure, byte[] result) + { + StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), result, 0); + } + + /// + /// 将数据从对象转换为二进制流。 + /// + /// 要转换的对象的类型。 + /// 要转换的对象。 + /// 要转换的对象的大小。 + /// 存储转换结果的二进制流。 + internal static void StructureToBytes(T structure, int structureSize, byte[] result) + { + StructureToBytes(structure, structureSize, result, 0); + } + + /// + /// 将数据从对象转换为二进制流。 + /// + /// 要转换的对象的类型。 + /// 要转换的对象。 + /// 存储转换结果的二进制流。 + /// 写入存储转换结果的二进制流的起始位置。 + public static void StructureToBytes(T structure, byte[] result, int startIndex) + { + StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), result, startIndex); + } + + /// + /// 将数据从对象转换为二进制流。 + /// + /// 要转换的对象的类型。 + /// 要转换的对象。 + /// 要转换的对象的大小。 + /// 存储转换结果的二进制流。 + /// 写入存储转换结果的二进制流的起始位置。 + internal static void StructureToBytes(T structure, int structureSize, byte[] result, int startIndex) + { + if (structureSize < 0) + { + throw new GameFrameworkException("Structure size is invalid."); + } + + if (result == null) + { + throw new GameFrameworkException("Result is invalid."); + } + + if (startIndex < 0) + { + throw new GameFrameworkException("Start index is invalid."); + } + + if (startIndex + structureSize > result.Length) + { + throw new GameFrameworkException("Result length is not enough."); + } + + EnsureCachedHGlobalSize(structureSize); + System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true); + System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, startIndex, structureSize); + } + + /// + /// 将数据从二进制流转换为对象。 + /// + /// 要转换的对象的类型。 + /// 要转换的二进制流。 + /// 存储转换结果的对象。 + public static T BytesToStructure(byte[] buffer) + { + return BytesToStructure(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, 0); + } + + /// + /// 将数据从二进制流转换为对象。 + /// + /// 要转换的对象的类型。 + /// 要转换的二进制流。 + /// 读取要转换的二进制流的起始位置。 + /// 存储转换结果的对象。 + public static T BytesToStructure(byte[] buffer, int startIndex) + { + return BytesToStructure(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, startIndex); + } + + /// + /// 将数据从二进制流转换为对象。 + /// + /// 要转换的对象的类型。 + /// 要转换的对象的大小。 + /// 要转换的二进制流。 + /// 存储转换结果的对象。 + internal static T BytesToStructure(int structureSize, byte[] buffer) + { + return BytesToStructure(structureSize, buffer, 0); + } + + /// + /// 将数据从二进制流转换为对象。 + /// + /// 要转换的对象的类型。 + /// 要转换的对象的大小。 + /// 要转换的二进制流。 + /// 读取要转换的二进制流的起始位置。 + /// 存储转换结果的对象。 + internal static T BytesToStructure(int structureSize, byte[] buffer, int startIndex) + { + if (structureSize < 0) + { + throw new GameFrameworkException("Structure size is invalid."); + } + + if (buffer == null) + { + throw new GameFrameworkException("Buffer is invalid."); + } + + if (startIndex < 0) + { + throw new GameFrameworkException("Start index is invalid."); + } + + if (startIndex + structureSize > buffer.Length) + { + throw new GameFrameworkException("Buffer length is not enough."); + } + + EnsureCachedHGlobalSize(structureSize); + System.Runtime.InteropServices.Marshal.Copy(buffer, startIndex, s_CachedHGlobalPtr, structureSize); + return (T)System.Runtime.InteropServices.Marshal.PtrToStructure(s_CachedHGlobalPtr, typeof(T)); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Marshal.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Marshal.cs.meta new file mode 100644 index 0000000..976aa19 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Marshal.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1c8a66fce3964f4588dda74e6b49919 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Path.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Path.cs new file mode 100644 index 0000000..9311135 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Path.cs @@ -0,0 +1,100 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.IO; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// 路径相关的实用函数。 + /// + public static class Path + { + /// + /// 获取规范的路径。 + /// + /// 要规范的路径。 + /// 规范的路径。 + public static string GetRegularPath(string path) + { + if (path == null) + { + return null; + } + + return path.Replace('\\', '/'); + } + + /// + /// 获取远程格式的路径(带有file:// 或 http:// 前缀)。 + /// + /// 原始路径。 + /// 远程格式路径。 + public static string GetRemotePath(string path) + { + string regularPath = GetRegularPath(path); + if (regularPath == null) + { + return null; + } + + return regularPath.Contains("://") ? regularPath : ("file:///" + regularPath).Replace("file:////", "file:///"); + } + + /// + /// 移除空文件夹。 + /// + /// 要处理的文件夹名称。 + /// 是否移除空文件夹成功。 + public static bool RemoveEmptyDirectory(string directoryName) + { + if (string.IsNullOrEmpty(directoryName)) + { + throw new GameFrameworkException("Directory name is invalid."); + } + + try + { + if (!Directory.Exists(directoryName)) + { + return false; + } + + // 不使用 SearchOption.AllDirectories,以便于在可能产生异常的环境下删除尽可能多的目录 + string[] subDirectoryNames = Directory.GetDirectories(directoryName, "*"); + int subDirectoryCount = subDirectoryNames.Length; + foreach (string subDirectoryName in subDirectoryNames) + { + if (RemoveEmptyDirectory(subDirectoryName)) + { + subDirectoryCount--; + } + } + + if (subDirectoryCount > 0) + { + return false; + } + + if (Directory.GetFiles(directoryName, "*").Length > 0) + { + return false; + } + + Directory.Delete(directoryName); + return true; + } + catch + { + return false; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Path.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Path.cs.meta new file mode 100644 index 0000000..d0ba2ff --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Path.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3595ba8a0743b91458204379ef60da6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Random.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Random.cs new file mode 100644 index 0000000..1bfccf1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Random.cs @@ -0,0 +1,79 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// 随机相关的实用函数。 + /// + public static class Random + { + private static System.Random s_Random = new System.Random((int)DateTime.UtcNow.Ticks); + + /// + /// 设置随机数种子。 + /// + /// 随机数种子。 + public static void SetSeed(int seed) + { + s_Random = new System.Random(seed); + } + + /// + /// 返回非负随机数。 + /// + /// 大于等于零且小于 System.Int32.MaxValue 的 32 位带符号整数。 + public static int GetRandom() + { + return s_Random.Next(); + } + + /// + /// 返回一个小于所指定最大值的非负随机数。 + /// + /// 要生成的随机数的上界(随机数不能取该上界值)。maxValue 必须大于等于零。 + /// 大于等于零且小于 maxValue 的 32 位带符号整数,即:返回值的范围通常包括零但不包括 maxValue。不过,如果 maxValue 等于零,则返回 maxValue。 + public static int GetRandom(int maxValue) + { + return s_Random.Next(maxValue); + } + + /// + /// 返回一个指定范围内的随机数。 + /// + /// 返回的随机数的下界(随机数可取该下界值)。 + /// 返回的随机数的上界(随机数不能取该上界值)。maxValue 必须大于等于 minValue。 + /// 一个大于等于 minValue 且小于 maxValue 的 32 位带符号整数,即:返回的值范围包括 minValue 但不包括 maxValue。如果 minValue 等于 maxValue,则返回 minValue。 + public static int GetRandom(int minValue, int maxValue) + { + return s_Random.Next(minValue, maxValue); + } + + /// + /// 返回一个介于 0.0 和 1.0 之间的随机数。 + /// + /// 大于等于 0.0 并且小于 1.0 的双精度浮点数。 + public static double GetRandomDouble() + { + return s_Random.NextDouble(); + } + + /// + /// 用随机数填充指定字节数组的元素。 + /// + /// 包含随机数的字节数组。 + public static void GetRandomBytes(byte[] buffer) + { + s_Random.NextBytes(buffer); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Random.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Random.cs.meta new file mode 100644 index 0000000..2c11839 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Random.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44c9b20e14037994c98d0cb677471c2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.ITextHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.ITextHelper.cs new file mode 100644 index 0000000..a8f115d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.ITextHelper.cs @@ -0,0 +1,405 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + public static partial class Utility + { + public static partial class Text + { + /// + /// 字符辅助器接口。 + /// + public interface ITextHelper + { + /// + /// 获取格式化字符串。 + /// + /// 字符串参数的类型。 + /// 字符串格式。 + /// 字符串参数。 + /// 格式化后的字符串。 + string Format(string format, T arg); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串参数 15 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 字符串参数 15。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串参数 15 的类型。 + /// 字符串参数 16 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 字符串参数 15。 + /// 字符串参数 16。 + /// 格式化后的字符串。 + string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.ITextHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.ITextHelper.cs.meta new file mode 100644 index 0000000..25230cc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.ITextHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 307f762c164f0794ab24bfba8df1cb7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.cs new file mode 100644 index 0000000..e5e5ccd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.cs @@ -0,0 +1,621 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// 字符相关的实用函数。 + /// + public static partial class Text + { + private static ITextHelper s_TextHelper = null; + + /// + /// 设置字符辅助器。 + /// + /// 要设置的字符辅助器。 + public static void SetTextHelper(ITextHelper textHelper) + { + s_TextHelper = textHelper; + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数的类型。 + /// 字符串格式。 + /// 字符串参数。 + /// 格式化后的字符串。 + public static string Format(string format, T arg) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg); + } + + return s_TextHelper.Format(format, arg); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2); + } + + return s_TextHelper.Format(format, arg1, arg2); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串参数 15 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 字符串参数 15。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串参数 15 的类型。 + /// 字符串参数 16 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 字符串参数 15。 + /// 字符串参数 16。 + /// 格式化后的字符串。 + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + if (s_TextHelper == null) + { + return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + + return s_TextHelper.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.cs.meta new file mode 100644 index 0000000..f152514 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Text.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24bccde1da28e4e41b23d685a3717db6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.Crc32.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.Crc32.cs new file mode 100644 index 0000000..673677d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.Crc32.cs @@ -0,0 +1,94 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + public static partial class Utility + { + public static partial class Verifier + { + /// + /// CRC32 算法。 + /// + private sealed class Crc32 + { + private const int TableLength = 256; + private const uint DefaultPolynomial = 0xedb88320; + private const uint DefaultSeed = 0xffffffff; + + private readonly uint m_Seed; + private readonly uint[] m_Table; + private uint m_Hash; + + public Crc32() + : this(DefaultPolynomial, DefaultSeed) + { + } + + public Crc32(uint polynomial, uint seed) + { + m_Seed = seed; + m_Table = InitializeTable(polynomial); + m_Hash = seed; + } + + public void Initialize() + { + m_Hash = m_Seed; + } + + public void HashCore(byte[] bytes, int offset, int length) + { + m_Hash = CalculateHash(m_Table, m_Hash, bytes, offset, length); + } + + public uint HashFinal() + { + return ~m_Hash; + } + + private static uint CalculateHash(uint[] table, uint value, byte[] bytes, int offset, int length) + { + int last = offset + length; + for (int i = offset; i < last; i++) + { + unchecked + { + value = (value >> 8) ^ table[bytes[i] ^ value & 0xff]; + } + } + + return value; + } + + private static uint[] InitializeTable(uint polynomial) + { + uint[] table = new uint[TableLength]; + for (int i = 0; i < TableLength; i++) + { + uint entry = (uint)i; + for (int j = 0; j < 8; j++) + { + if ((entry & 1) == 1) + { + entry = (entry >> 1) ^ polynomial; + } + else + { + entry >>= 1; + } + } + + table[i] = entry; + } + + return table; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.Crc32.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.Crc32.cs.meta new file mode 100644 index 0000000..d009d76 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.Crc32.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: faf9c03d5beeb1e4a9ae0cd1e8fd80a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.cs new file mode 100644 index 0000000..1ab5529 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.cs @@ -0,0 +1,195 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.IO; + +namespace GameFramework +{ + public static partial class Utility + { + /// + /// 校验相关的实用函数。 + /// + public static partial class Verifier + { + private const int CachedBytesLength = 0x1000; + private static readonly byte[] s_CachedBytes = new byte[CachedBytesLength]; + private static readonly Crc32 s_Algorithm = new Crc32(); + + /// + /// 计算二进制流的 CRC32。 + /// + /// 指定的二进制流。 + /// 计算后的 CRC32。 + public static int GetCrc32(byte[] bytes) + { + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + return GetCrc32(bytes, 0, bytes.Length); + } + + /// + /// 计算二进制流的 CRC32。 + /// + /// 指定的二进制流。 + /// 二进制流的偏移。 + /// 二进制流的长度。 + /// 计算后的 CRC32。 + public static int GetCrc32(byte[] bytes, int offset, int length) + { + if (bytes == null) + { + throw new GameFrameworkException("Bytes is invalid."); + } + + if (offset < 0 || length < 0 || offset + length > bytes.Length) + { + throw new GameFrameworkException("Offset or length is invalid."); + } + + s_Algorithm.HashCore(bytes, offset, length); + int result = (int)s_Algorithm.HashFinal(); + s_Algorithm.Initialize(); + return result; + } + + /// + /// 计算二进制流的 CRC32。 + /// + /// 指定的二进制流。 + /// 计算后的 CRC32。 + public static int GetCrc32(Stream stream) + { + if (stream == null) + { + throw new GameFrameworkException("Stream is invalid."); + } + + while (true) + { + int bytesRead = stream.Read(s_CachedBytes, 0, CachedBytesLength); + if (bytesRead > 0) + { + s_Algorithm.HashCore(s_CachedBytes, 0, bytesRead); + } + else + { + break; + } + } + + int result = (int)s_Algorithm.HashFinal(); + s_Algorithm.Initialize(); + Array.Clear(s_CachedBytes, 0, CachedBytesLength); + return result; + } + + /// + /// 获取 CRC32 数值的二进制数组。 + /// + /// CRC32 数值。 + /// CRC32 数值的二进制数组。 + public static byte[] GetCrc32Bytes(int crc32) + { + return new byte[] { (byte)((crc32 >> 24) & 0xff), (byte)((crc32 >> 16) & 0xff), (byte)((crc32 >> 8) & 0xff), (byte)(crc32 & 0xff) }; + } + + /// + /// 获取 CRC32 数值的二进制数组。 + /// + /// CRC32 数值。 + /// 要存放结果的数组。 + public static void GetCrc32Bytes(int crc32, byte[] bytes) + { + GetCrc32Bytes(crc32, bytes, 0); + } + + /// + /// 获取 CRC32 数值的二进制数组。 + /// + /// CRC32 数值。 + /// 要存放结果的数组。 + /// CRC32 数值的二进制数组在结果数组内的起始位置。 + public static void GetCrc32Bytes(int crc32, byte[] bytes, int offset) + { + if (bytes == null) + { + throw new GameFrameworkException("Result is invalid."); + } + + if (offset < 0 || offset + 4 > bytes.Length) + { + throw new GameFrameworkException("Offset or length is invalid."); + } + + bytes[offset] = (byte)((crc32 >> 24) & 0xff); + bytes[offset + 1] = (byte)((crc32 >> 16) & 0xff); + bytes[offset + 2] = (byte)((crc32 >> 8) & 0xff); + bytes[offset + 3] = (byte)(crc32 & 0xff); + } + + internal static int GetCrc32(Stream stream, byte[] code, int length) + { + if (stream == null) + { + throw new GameFrameworkException("Stream is invalid."); + } + + if (code == null) + { + throw new GameFrameworkException("Code is invalid."); + } + + int codeLength = code.Length; + if (codeLength <= 0) + { + throw new GameFrameworkException("Code length is invalid."); + } + + int bytesLength = (int)stream.Length; + if (length < 0 || length > bytesLength) + { + length = bytesLength; + } + + int codeIndex = 0; + while (true) + { + int bytesRead = stream.Read(s_CachedBytes, 0, CachedBytesLength); + if (bytesRead > 0) + { + if (length > 0) + { + for (int i = 0; i < bytesRead && i < length; i++) + { + s_CachedBytes[i] ^= code[codeIndex++]; + codeIndex %= codeLength; + } + + length -= bytesRead; + } + + s_Algorithm.HashCore(s_CachedBytes, 0, bytesRead); + } + else + { + break; + } + } + + int result = (int)s_Algorithm.HashFinal(); + s_Algorithm.Initialize(); + Array.Clear(s_CachedBytes, 0, CachedBytesLength); + return result; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.cs.meta new file mode 100644 index 0000000..d48180c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.Verifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2635809a199845647be4647122414003 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.cs new file mode 100644 index 0000000..f713195 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework +{ + /// + /// 实用函数集。 + /// + public static partial class Utility + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.cs.meta new file mode 100644 index 0000000..cdce1bf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/Utility/Utility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca58825e822b0544bb50667e99cde3db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest.meta new file mode 100644 index 0000000..497b607 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: edab58e22a981c24ebbf4b9e64b26f5c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/Constant.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/Constant.cs new file mode 100644 index 0000000..bf5e8f9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/Constant.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求相关常量。 + /// + internal static class Constant + { + /// + /// 默认 Web 请求任务优先级。 + /// + internal const int DefaultPriority = 0; + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/Constant.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/Constant.cs.meta new file mode 100644 index 0000000..8c85587 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/Constant.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5aa39fab3ac22cf4994d6b228ccd2f64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestAgentHelper.cs new file mode 100644 index 0000000..994447b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestAgentHelper.cs @@ -0,0 +1,47 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求代理辅助器接口。 + /// + public interface IWebRequestAgentHelper + { + /// + /// Web 请求代理辅助器完成事件。 + /// + event EventHandler WebRequestAgentHelperComplete; + + /// + /// Web 请求代理辅助器错误事件。 + /// + event EventHandler WebRequestAgentHelperError; + + /// + /// 通过 Web 请求代理辅助器发送 Web 请求。 + /// + /// Web 请求地址。 + /// 用户自定义数据。 + void Request(string webRequestUri, object userData); + + /// + /// 通过 Web 请求代理辅助器发送 Web 请求。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// 用户自定义数据。 + void Request(string webRequestUri, byte[] postData, object userData); + + /// + /// 重置 Web 请求代理辅助器。 + /// + void Reset(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestAgentHelper.cs.meta new file mode 100644 index 0000000..71a9616 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 087454fb195eea246a3261448e5fc8f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestManager.cs new file mode 100644 index 0000000..b51cf55 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestManager.cs @@ -0,0 +1,277 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求管理器接口。 + /// + public interface IWebRequestManager + { + /// + /// 获取 Web 请求代理总数量。 + /// + int TotalAgentCount + { + get; + } + + /// + /// 获取可用 Web 请求代理数量。 + /// + int FreeAgentCount + { + get; + } + + /// + /// 获取工作中 Web 请求代理数量。 + /// + int WorkingAgentCount + { + get; + } + + /// + /// 获取等待 Web 请求数量。 + /// + int WaitingTaskCount + { + get; + } + + /// + /// 获取或设置 Web 请求超时时长,以秒为单位。 + /// + float Timeout + { + get; + set; + } + + /// + /// Web 请求开始事件。 + /// + event EventHandler WebRequestStart; + + /// + /// Web 请求成功事件。 + /// + event EventHandler WebRequestSuccess; + + /// + /// Web 请求失败事件。 + /// + event EventHandler WebRequestFailure; + + /// + /// 增加 Web 请求代理辅助器。 + /// + /// 要增加的 Web 请求代理辅助器。 + void AddWebRequestAgentHelper(IWebRequestAgentHelper webRequestAgentHelper); + + /// + /// 根据 Web 请求任务的序列编号获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的序列编号。 + /// Web 请求任务的信息。 + TaskInfo GetWebRequestInfo(int serialId); + + /// + /// 根据 Web 请求任务的标签获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的标签。 + /// Web 请求任务的信息。 + TaskInfo[] GetWebRequestInfos(string tag); + + /// + /// 根据 Web 请求任务的标签获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的标签。 + /// Web 请求任务的信息。 + void GetAllWebRequestInfos(string tag, List results); + + /// + /// 获取所有 Web 请求任务的信息。 + /// + /// 所有 Web 请求任务的信息。 + TaskInfo[] GetAllWebRequestInfos(); + + /// + /// 获取所有 Web 请求任务的信息。 + /// + /// 所有 Web 请求任务的信息。 + void GetAllWebRequestInfos(List results); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, byte[] postData); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, string tag); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, int priority); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, object userData); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, byte[] postData, string tag); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, byte[] postData, int priority); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, byte[] postData, object userData); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, string tag, int priority); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, string tag, object userData); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, int priority, object userData); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, byte[] postData, string tag, int priority); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, byte[] postData, string tag, object userData); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, byte[] postData, int priority, object userData); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, string tag, int priority, object userData); + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + int AddWebRequest(string webRequestUri, byte[] postData, string tag, int priority, object userData); + + /// + /// 根据 Web 请求任务的序列编号移除 Web 请求任务。 + /// + /// 要移除 Web 请求任务的序列编号。 + /// 是否移除 Web 请求任务成功。 + bool RemoveWebRequest(int serialId); + + /// + /// 根据 Web 请求任务的标签移除 Web 请求任务。 + /// + /// 要移除 Web 请求任务的标签。 + /// 移除 Web 请求任务的数量。 + int RemoveWebRequests(string tag); + + /// + /// 移除所有 Web 请求任务。 + /// + /// 移除 Web 请求任务的数量。 + int RemoveAllWebRequests(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestManager.cs.meta new file mode 100644 index 0000000..a8058c1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/IWebRequestManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45df1d440bdd6dc4988347c1ca3a7c3f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperCompleteEventArgs.cs new file mode 100644 index 0000000..c9ebcab --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperCompleteEventArgs.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求代理辅助器完成事件。 + /// + public sealed class WebRequestAgentHelperCompleteEventArgs : GameFrameworkEventArgs + { + private byte[] m_WebResponseBytes; + + /// + /// 初始化 Web 请求代理辅助器完成事件的新实例。 + /// + public WebRequestAgentHelperCompleteEventArgs() + { + m_WebResponseBytes = null; + } + + /// + /// 创建 Web 请求代理辅助器完成事件。 + /// + /// Web 响应的数据流。 + /// 创建的 Web 请求代理辅助器完成事件。 + public static WebRequestAgentHelperCompleteEventArgs Create(byte[] webResponseBytes) + { + WebRequestAgentHelperCompleteEventArgs webRequestAgentHelperCompleteEventArgs = ReferencePool.Acquire(); + webRequestAgentHelperCompleteEventArgs.m_WebResponseBytes = webResponseBytes; + return webRequestAgentHelperCompleteEventArgs; + } + + /// + /// 清理 Web 请求代理辅助器完成事件。 + /// + public override void Clear() + { + m_WebResponseBytes = null; + } + + /// + /// 获取 Web 响应的数据流。 + /// + /// Web 响应的数据流。 + public byte[] GetWebResponseBytes() + { + return m_WebResponseBytes; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperCompleteEventArgs.cs.meta new file mode 100644 index 0000000..363f0c1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ab455894b86c6246b5c74bc0713ef59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperErrorEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperErrorEventArgs.cs new file mode 100644 index 0000000..e035d0c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperErrorEventArgs.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求代理辅助器错误事件。 + /// + public sealed class WebRequestAgentHelperErrorEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化 Web 请求代理辅助器错误事件的新实例。 + /// + public WebRequestAgentHelperErrorEventArgs() + { + ErrorMessage = null; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建 Web 请求代理辅助器错误事件。 + /// + /// 错误信息。 + /// 创建的 Web 请求代理辅助器错误事件。 + public static WebRequestAgentHelperErrorEventArgs Create(string errorMessage) + { + WebRequestAgentHelperErrorEventArgs webRequestAgentHelperErrorEventArgs = ReferencePool.Acquire(); + webRequestAgentHelperErrorEventArgs.ErrorMessage = errorMessage; + return webRequestAgentHelperErrorEventArgs; + } + + /// + /// 清理 Web 请求代理辅助器错误事件。 + /// + public override void Clear() + { + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperErrorEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperErrorEventArgs.cs.meta new file mode 100644 index 0000000..1212d80 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestAgentHelperErrorEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 879f5108f24ee8143a20f8441a02ba56 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestFailureEventArgs.cs new file mode 100644 index 0000000..72799ee --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestFailureEventArgs.cs @@ -0,0 +1,91 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求失败事件。 + /// + public sealed class WebRequestFailureEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化 Web 请求失败事件的新实例。 + /// + public WebRequestFailureEventArgs() + { + SerialId = 0; + WebRequestUri = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取 Web 请求任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取 Web 请求地址。 + /// + public string WebRequestUri + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建 Web 请求失败事件。 + /// + /// Web 请求任务的序列编号。 + /// Web 请求地址。 + /// 错误信息。 + /// 用户自定义数据。 + /// 创建的 Web 请求失败事件。 + public static WebRequestFailureEventArgs Create(int serialId, string webRequestUri, string errorMessage, object userData) + { + WebRequestFailureEventArgs webRequestFailureEventArgs = ReferencePool.Acquire(); + webRequestFailureEventArgs.SerialId = serialId; + webRequestFailureEventArgs.WebRequestUri = webRequestUri; + webRequestFailureEventArgs.ErrorMessage = errorMessage; + webRequestFailureEventArgs.UserData = userData; + return webRequestFailureEventArgs; + } + + /// + /// 清理 Web 请求失败事件。 + /// + public override void Clear() + { + SerialId = 0; + WebRequestUri = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestFailureEventArgs.cs.meta new file mode 100644 index 0000000..3b1a56f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 660f466cc1a44f643bfb3ddc2e3e6b06 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestAgent.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestAgent.cs new file mode 100644 index 0000000..b79d8ad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestAgent.cs @@ -0,0 +1,176 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + internal sealed partial class WebRequestManager : GameFrameworkModule, IWebRequestManager + { + /// + /// Web 请求代理。 + /// + private sealed class WebRequestAgent : ITaskAgent + { + private readonly IWebRequestAgentHelper m_Helper; + private WebRequestTask m_Task; + private float m_WaitTime; + + public GameFrameworkAction WebRequestAgentStart; + public GameFrameworkAction WebRequestAgentSuccess; + public GameFrameworkAction WebRequestAgentFailure; + + /// + /// 初始化 Web 请求代理的新实例。 + /// + /// Web 请求代理辅助器。 + public WebRequestAgent(IWebRequestAgentHelper webRequestAgentHelper) + { + if (webRequestAgentHelper == null) + { + throw new GameFrameworkException("Web request agent helper is invalid."); + } + + m_Helper = webRequestAgentHelper; + m_Task = null; + m_WaitTime = 0f; + + WebRequestAgentStart = null; + WebRequestAgentSuccess = null; + WebRequestAgentFailure = null; + } + + /// + /// 获取 Web 请求任务。 + /// + public WebRequestTask Task + { + get + { + return m_Task; + } + } + + /// + /// 获取已经等待时间。 + /// + public float WaitTime + { + get + { + return m_WaitTime; + } + } + + /// + /// 初始化 Web 请求代理。 + /// + public void Initialize() + { + m_Helper.WebRequestAgentHelperComplete += OnWebRequestAgentHelperComplete; + m_Helper.WebRequestAgentHelperError += OnWebRequestAgentHelperError; + } + + /// + /// Web 请求代理轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_Task.Status == WebRequestTaskStatus.Doing) + { + m_WaitTime += realElapseSeconds; + if (m_WaitTime >= m_Task.Timeout) + { + WebRequestAgentHelperErrorEventArgs webRequestAgentHelperErrorEventArgs = WebRequestAgentHelperErrorEventArgs.Create("Timeout"); + OnWebRequestAgentHelperError(this, webRequestAgentHelperErrorEventArgs); + ReferencePool.Release(webRequestAgentHelperErrorEventArgs); + } + } + } + + /// + /// 关闭并清理 Web 请求代理。 + /// + public void Shutdown() + { + Reset(); + m_Helper.WebRequestAgentHelperComplete -= OnWebRequestAgentHelperComplete; + m_Helper.WebRequestAgentHelperError -= OnWebRequestAgentHelperError; + } + + /// + /// 开始处理 Web 请求任务。 + /// + /// 要处理的 Web 请求任务。 + /// 开始处理任务的状态。 + public StartTaskStatus Start(WebRequestTask task) + { + if (task == null) + { + throw new GameFrameworkException("Task is invalid."); + } + + m_Task = task; + m_Task.Status = WebRequestTaskStatus.Doing; + + if (WebRequestAgentStart != null) + { + WebRequestAgentStart(this); + } + + byte[] postData = m_Task.GetPostData(); + if (postData == null) + { + m_Helper.Request(m_Task.WebRequestUri, m_Task.UserData); + } + else + { + m_Helper.Request(m_Task.WebRequestUri, postData, m_Task.UserData); + } + + m_WaitTime = 0f; + return StartTaskStatus.CanResume; + } + + /// + /// 重置 Web 请求代理。 + /// + public void Reset() + { + m_Helper.Reset(); + m_Task = null; + m_WaitTime = 0f; + } + + private void OnWebRequestAgentHelperComplete(object sender, WebRequestAgentHelperCompleteEventArgs e) + { + m_Helper.Reset(); + m_Task.Status = WebRequestTaskStatus.Done; + + if (WebRequestAgentSuccess != null) + { + WebRequestAgentSuccess(this, e.GetWebResponseBytes()); + } + + m_Task.Done = true; + } + + private void OnWebRequestAgentHelperError(object sender, WebRequestAgentHelperErrorEventArgs e) + { + m_Helper.Reset(); + m_Task.Status = WebRequestTaskStatus.Error; + + if (WebRequestAgentFailure != null) + { + WebRequestAgentFailure(this, e.ErrorMessage); + } + + m_Task.Done = true; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestAgent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestAgent.cs.meta new file mode 100644 index 0000000..00c5fea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestAgent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: acd6a4551781afa449250e1e652a8970 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTask.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTask.cs new file mode 100644 index 0000000..e07a345 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTask.cs @@ -0,0 +1,121 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + internal sealed partial class WebRequestManager : GameFrameworkModule, IWebRequestManager + { + /// + /// Web 请求任务。 + /// + private sealed class WebRequestTask : TaskBase + { + private static int s_Serial = 0; + + private WebRequestTaskStatus m_Status; + private string m_WebRequestUri; + private byte[] m_PostData; + private float m_Timeout; + + public WebRequestTask() + { + m_Status = WebRequestTaskStatus.Todo; + m_WebRequestUri = null; + m_PostData = null; + m_Timeout = 0f; + } + + /// + /// 获取或设置 Web 请求任务的状态。 + /// + public WebRequestTaskStatus Status + { + get + { + return m_Status; + } + set + { + m_Status = value; + } + } + + /// + /// 获取要发送的远程地址。 + /// + public string WebRequestUri + { + get + { + return m_WebRequestUri; + } + } + + /// + /// 获取 Web 请求超时时长,以秒为单位。 + /// + public float Timeout + { + get + { + return m_Timeout; + } + } + + /// + /// 获取 Web 请求任务的描述。 + /// + public override string Description + { + get + { + return m_WebRequestUri; + } + } + + /// + /// 创建 Web 请求任务。 + /// + /// 要发送的远程地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 下载超时时长,以秒为单位。 + /// 用户自定义数据。 + /// 创建的 Web 请求任务。 + public static WebRequestTask Create(string webRequestUri, byte[] postData, string tag, int priority, float timeout, object userData) + { + WebRequestTask webRequestTask = ReferencePool.Acquire(); + webRequestTask.Initialize(++s_Serial, tag, priority, userData); + webRequestTask.m_WebRequestUri = webRequestUri; + webRequestTask.m_PostData = postData; + webRequestTask.m_Timeout = timeout; + return webRequestTask; + } + + /// + /// 清理 Web 请求任务。 + /// + public override void Clear() + { + base.Clear(); + m_Status = WebRequestTaskStatus.Todo; + m_WebRequestUri = null; + m_PostData = null; + m_Timeout = 0f; + } + + /// + /// 获取要发送的数据流。 + /// + public byte[] GetPostData() + { + return m_PostData; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTask.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTask.cs.meta new file mode 100644 index 0000000..5b022f0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa35a8348bbf90247afaf20a551478de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTaskStatus.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTaskStatus.cs new file mode 100644 index 0000000..61d8296 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTaskStatus.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + internal sealed partial class WebRequestManager : GameFrameworkModule, IWebRequestManager + { + /// + /// Web 请求任务的状态。 + /// + private enum WebRequestTaskStatus : byte + { + /// + /// 准备请求。 + /// + Todo = 0, + + /// + /// 请求中。 + /// + Doing, + + /// + /// 请求完成。 + /// + Done, + + /// + /// 请求错误。 + /// + Error + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTaskStatus.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTaskStatus.cs.meta new file mode 100644 index 0000000..0e08e8a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.WebRequestTaskStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1dd215640353a984bb49aa4532b5a4ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.cs new file mode 100644 index 0000000..4d8bb51 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.cs @@ -0,0 +1,483 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求管理器。 + /// + internal sealed partial class WebRequestManager : GameFrameworkModule, IWebRequestManager + { + private readonly TaskPool m_TaskPool; + private float m_Timeout; + private EventHandler m_WebRequestStartEventHandler; + private EventHandler m_WebRequestSuccessEventHandler; + private EventHandler m_WebRequestFailureEventHandler; + + /// + /// 初始化 Web 请求管理器的新实例。 + /// + public WebRequestManager() + { + m_TaskPool = new TaskPool(); + m_Timeout = 30f; + m_WebRequestStartEventHandler = null; + m_WebRequestSuccessEventHandler = null; + m_WebRequestFailureEventHandler = null; + } + + /// + /// 获取 Web 请求代理总数量。 + /// + public int TotalAgentCount + { + get + { + return m_TaskPool.TotalAgentCount; + } + } + + /// + /// 获取可用 Web 请求代理数量。 + /// + public int FreeAgentCount + { + get + { + return m_TaskPool.FreeAgentCount; + } + } + + /// + /// 获取工作中 Web 请求代理数量。 + /// + public int WorkingAgentCount + { + get + { + return m_TaskPool.WorkingAgentCount; + } + } + + /// + /// 获取等待 Web 请求数量。 + /// + public int WaitingTaskCount + { + get + { + return m_TaskPool.WaitingTaskCount; + } + } + + /// + /// 获取或设置 Web 请求超时时长,以秒为单位。 + /// + public float Timeout + { + get + { + return m_Timeout; + } + set + { + m_Timeout = value; + } + } + + /// + /// Web 请求开始事件。 + /// + public event EventHandler WebRequestStart + { + add + { + m_WebRequestStartEventHandler += value; + } + remove + { + m_WebRequestStartEventHandler -= value; + } + } + + /// + /// Web 请求成功事件。 + /// + public event EventHandler WebRequestSuccess + { + add + { + m_WebRequestSuccessEventHandler += value; + } + remove + { + m_WebRequestSuccessEventHandler -= value; + } + } + + /// + /// Web 请求失败事件。 + /// + public event EventHandler WebRequestFailure + { + add + { + m_WebRequestFailureEventHandler += value; + } + remove + { + m_WebRequestFailureEventHandler -= value; + } + } + + /// + /// Web 请求管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + m_TaskPool.Update(elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理 Web 请求管理器。 + /// + internal override void Shutdown() + { + m_TaskPool.Shutdown(); + } + + /// + /// 增加 Web 请求代理辅助器。 + /// + /// 要增加的 Web 请求代理辅助器。 + public void AddWebRequestAgentHelper(IWebRequestAgentHelper webRequestAgentHelper) + { + WebRequestAgent agent = new WebRequestAgent(webRequestAgentHelper); + agent.WebRequestAgentStart += OnWebRequestAgentStart; + agent.WebRequestAgentSuccess += OnWebRequestAgentSuccess; + agent.WebRequestAgentFailure += OnWebRequestAgentFailure; + + m_TaskPool.AddAgent(agent); + } + + /// + /// 根据 Web 请求任务的序列编号获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的序列编号。 + /// Web 请求任务的信息。 + public TaskInfo GetWebRequestInfo(int serialId) + { + return m_TaskPool.GetTaskInfo(serialId); + } + + /// + /// 根据 Web 请求任务的标签获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的标签。 + /// Web 请求任务的信息。 + public TaskInfo[] GetWebRequestInfos(string tag) + { + return m_TaskPool.GetTaskInfos(tag); + } + + /// + /// 根据 Web 请求任务的标签获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的标签。 + /// Web 请求任务的信息。 + public void GetAllWebRequestInfos(string tag, List results) + { + m_TaskPool.GetTaskInfos(tag, results); + } + + /// + /// 获取所有 Web 请求任务的信息。 + /// + /// 所有 Web 请求任务的信息。 + public TaskInfo[] GetAllWebRequestInfos() + { + return m_TaskPool.GetAllTaskInfos(); + } + + /// + /// 获取所有 Web 请求任务的信息。 + /// + /// 所有 Web 请求任务的信息。 + public void GetAllWebRequestInfos(List results) + { + m_TaskPool.GetAllTaskInfos(results); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri) + { + return AddWebRequest(webRequestUri, null, null, Constant.DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData) + { + return AddWebRequest(webRequestUri, postData, null, Constant.DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, string tag) + { + return AddWebRequest(webRequestUri, null, tag, Constant.DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, int priority) + { + return AddWebRequest(webRequestUri, null, null, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, object userData) + { + return AddWebRequest(webRequestUri, null, null, Constant.DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, string tag) + { + return AddWebRequest(webRequestUri, postData, tag, Constant.DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, int priority) + { + return AddWebRequest(webRequestUri, postData, null, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, object userData) + { + return AddWebRequest(webRequestUri, postData, null, Constant.DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, string tag, int priority) + { + return AddWebRequest(webRequestUri, null, tag, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, string tag, object userData) + { + return AddWebRequest(webRequestUri, null, tag, Constant.DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, int priority, object userData) + { + return AddWebRequest(webRequestUri, null, null, priority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, string tag, int priority) + { + return AddWebRequest(webRequestUri, postData, tag, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, string tag, object userData) + { + return AddWebRequest(webRequestUri, postData, tag, Constant.DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, int priority, object userData) + { + return AddWebRequest(webRequestUri, postData, null, priority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, string tag, int priority, object userData) + { + return AddWebRequest(webRequestUri, null, tag, priority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, string tag, int priority, object userData) + { + if (string.IsNullOrEmpty(webRequestUri)) + { + throw new GameFrameworkException("Web request uri is invalid."); + } + + if (TotalAgentCount <= 0) + { + throw new GameFrameworkException("You must add web request agent first."); + } + + WebRequestTask webRequestTask = WebRequestTask.Create(webRequestUri, postData, tag, priority, m_Timeout, userData); + m_TaskPool.AddTask(webRequestTask); + return webRequestTask.SerialId; + } + + /// + /// 根据 Web 请求任务的序列编号移除 Web 请求任务。 + /// + /// 要移除 Web 请求任务的序列编号。 + /// 是否移除 Web 请求任务成功。 + public bool RemoveWebRequest(int serialId) + { + return m_TaskPool.RemoveTask(serialId); + } + + /// + /// 根据 Web 请求任务的标签移除 Web 请求任务。 + /// + /// 要移除 Web 请求任务的标签。 + /// 移除 Web 请求任务的数量。 + public int RemoveWebRequests(string tag) + { + return m_TaskPool.RemoveTasks(tag); + } + + /// + /// 移除所有 Web 请求任务。 + /// + /// 移除 Web 请求任务的数量。 + public int RemoveAllWebRequests() + { + return m_TaskPool.RemoveAllTasks(); + } + + private void OnWebRequestAgentStart(WebRequestAgent sender) + { + if (m_WebRequestStartEventHandler != null) + { + WebRequestStartEventArgs webRequestStartEventArgs = WebRequestStartEventArgs.Create(sender.Task.SerialId, sender.Task.WebRequestUri, sender.Task.UserData); + m_WebRequestStartEventHandler(this, webRequestStartEventArgs); + ReferencePool.Release(webRequestStartEventArgs); + } + } + + private void OnWebRequestAgentSuccess(WebRequestAgent sender, byte[] webResponseBytes) + { + if (m_WebRequestSuccessEventHandler != null) + { + WebRequestSuccessEventArgs webRequestSuccessEventArgs = WebRequestSuccessEventArgs.Create(sender.Task.SerialId, sender.Task.WebRequestUri, webResponseBytes, sender.Task.UserData); + m_WebRequestSuccessEventHandler(this, webRequestSuccessEventArgs); + ReferencePool.Release(webRequestSuccessEventArgs); + } + } + + private void OnWebRequestAgentFailure(WebRequestAgent sender, string errorMessage) + { + if (m_WebRequestFailureEventHandler != null) + { + WebRequestFailureEventArgs webRequestFailureEventArgs = WebRequestFailureEventArgs.Create(sender.Task.SerialId, sender.Task.WebRequestUri, errorMessage, sender.Task.UserData); + m_WebRequestFailureEventHandler(this, webRequestFailureEventArgs); + ReferencePool.Release(webRequestFailureEventArgs); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.cs.meta new file mode 100644 index 0000000..3f4df34 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 18f1579932f9d484799d6477eda0e890 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestStartEventArgs.cs new file mode 100644 index 0000000..9490494 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestStartEventArgs.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求开始事件。 + /// + public sealed class WebRequestStartEventArgs : GameFrameworkEventArgs + { + /// + /// 初始化 Web 请求开始事件的新实例。 + /// + public WebRequestStartEventArgs() + { + SerialId = 0; + WebRequestUri = null; + UserData = null; + } + + /// + /// 获取 Web 请求任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取 Web 请求地址。 + /// + public string WebRequestUri + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建 Web 请求开始事件。 + /// + /// Web 请求任务的序列编号。 + /// Web 请求地址。 + /// 用户自定义数据。 + /// 创建的 Web 请求开始事件。 + public static WebRequestStartEventArgs Create(int serialId, string webRequestUri, object userData) + { + WebRequestStartEventArgs webRequestStartEventArgs = ReferencePool.Acquire(); + webRequestStartEventArgs.SerialId = serialId; + webRequestStartEventArgs.WebRequestUri = webRequestUri; + webRequestStartEventArgs.UserData = userData; + return webRequestStartEventArgs; + } + + /// + /// 清理 Web 请求开始事件。 + /// + public override void Clear() + { + SerialId = 0; + WebRequestUri = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestStartEventArgs.cs.meta new file mode 100644 index 0000000..880e59b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f796d4bd94f207449a87f46891c7a1d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestSuccessEventArgs.cs new file mode 100644 index 0000000..28da3a5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestSuccessEventArgs.cs @@ -0,0 +1,93 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace GameFramework.WebRequest +{ + /// + /// Web 请求成功事件。 + /// + public sealed class WebRequestSuccessEventArgs : GameFrameworkEventArgs + { + private byte[] m_WebResponseBytes; + + /// + /// 初始化 Web 请求成功事件的新实例。 + /// + public WebRequestSuccessEventArgs() + { + SerialId = 0; + WebRequestUri = null; + m_WebResponseBytes = null; + UserData = null; + } + + /// + /// 获取 Web 请求任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取 Web 请求地址。 + /// + public string WebRequestUri + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建 Web 请求成功事件。 + /// + /// Web 请求任务的序列编号。 + /// Web 请求地址。 + /// Web 响应的数据流。 + /// 用户自定义数据。 + /// 创建的 Web 请求成功事件。 + public static WebRequestSuccessEventArgs Create(int serialId, string webRequestUri, byte[] webResponseBytes, object userData) + { + WebRequestSuccessEventArgs webRequestSuccessEventArgs = ReferencePool.Acquire(); + webRequestSuccessEventArgs.SerialId = serialId; + webRequestSuccessEventArgs.WebRequestUri = webRequestUri; + webRequestSuccessEventArgs.m_WebResponseBytes = webResponseBytes; + webRequestSuccessEventArgs.UserData = userData; + return webRequestSuccessEventArgs; + } + + /// + /// 清理 Web 请求成功事件。 + /// + public override void Clear() + { + SerialId = 0; + WebRequestUri = null; + m_WebResponseBytes = null; + UserData = null; + } + + /// + /// 获取 Web 响应的数据流。 + /// + /// Web 响应的数据流。 + public byte[] GetWebResponseBytes() + { + return m_WebResponseBytes; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestSuccessEventArgs.cs.meta new file mode 100644 index 0000000..3d69330 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/GameFramework/WebRequest/WebRequestSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9389b80a791ad9445bfbf6018e15831f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework.meta new file mode 100644 index 0000000..d680382 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1b441bec1c7b6aa4f9d91763d2f9ed39 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base.meta new file mode 100644 index 0000000..abcd272 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fef53289940cb524687e31ef870f5029 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/BaseComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/BaseComponent.cs new file mode 100644 index 0000000..4126f26 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/BaseComponent.cs @@ -0,0 +1,425 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Localization; +using GameFramework.Resource; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 基础组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Base")] + public sealed class BaseComponent : GameFrameworkComponent + { + private const int DefaultDpi = 96; // default windows dpi + + private float m_GameSpeedBeforePause = 1f; + + [SerializeField] + private bool m_EditorResourceMode = true; + + [SerializeField] + private Language m_EditorLanguage = Language.Unspecified; + + [SerializeField] + private string m_TextHelperTypeName = "UnityGameFramework.Runtime.DefaultTextHelper"; + + [SerializeField] + private string m_VersionHelperTypeName = "UnityGameFramework.Runtime.DefaultVersionHelper"; + + [SerializeField] + private string m_LogHelperTypeName = "UnityGameFramework.Runtime.DefaultLogHelper"; + + [SerializeField] + private string m_CompressionHelperTypeName = "UnityGameFramework.Runtime.DefaultCompressionHelper"; + + [SerializeField] + private string m_JsonHelperTypeName = "UnityGameFramework.Runtime.DefaultJsonHelper"; + + [SerializeField] + private int m_FrameRate = 30; + + [SerializeField] + private float m_GameSpeed = 1f; + + [SerializeField] + private bool m_RunInBackground = true; + + [SerializeField] + private bool m_NeverSleep = true; + + /// + /// 获取或设置是否使用编辑器资源模式(仅编辑器内有效)。 + /// + public bool EditorResourceMode + { + get + { + return m_EditorResourceMode; + } + set + { + m_EditorResourceMode = value; + } + } + + /// + /// 获取或设置编辑器语言(仅编辑器内有效)。 + /// + public Language EditorLanguage + { + get + { + return m_EditorLanguage; + } + set + { + m_EditorLanguage = value; + } + } + + /// + /// 获取或设置编辑器资源辅助器。 + /// + public IResourceManager EditorResourceHelper + { + get; + set; + } + + /// + /// 获取或设置游戏帧率。 + /// + public int FrameRate + { + get + { + return m_FrameRate; + } + set + { + Application.targetFrameRate = m_FrameRate = value; + } + } + + /// + /// 获取或设置游戏速度。 + /// + public float GameSpeed + { + get + { + return m_GameSpeed; + } + set + { + Time.timeScale = m_GameSpeed = value >= 0f ? value : 0f; + } + } + + /// + /// 获取游戏是否暂停。 + /// + public bool IsGamePaused + { + get + { + return m_GameSpeed <= 0f; + } + } + + /// + /// 获取是否正常游戏速度。 + /// + public bool IsNormalGameSpeed + { + get + { + return m_GameSpeed == 1f; + } + } + + /// + /// 获取或设置是否允许后台运行。 + /// + public bool RunInBackground + { + get + { + return m_RunInBackground; + } + set + { + Application.runInBackground = m_RunInBackground = value; + } + } + + /// + /// 获取或设置是否禁止休眠。 + /// + public bool NeverSleep + { + get + { + return m_NeverSleep; + } + set + { + m_NeverSleep = value; + Screen.sleepTimeout = value ? SleepTimeout.NeverSleep : SleepTimeout.SystemSetting; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + InitTextHelper(); + InitVersionHelper(); + InitLogHelper(); + Log.Info("Game Framework Version: {0}", GameFramework.Version.GameFrameworkVersion); + Log.Info("Game Version: {0} ({1})", GameFramework.Version.GameVersion, GameFramework.Version.InternalGameVersion); + Log.Info("Unity Version: {0}", Application.unityVersion); + +#if UNITY_5_3_OR_NEWER || UNITY_5_3 + InitCompressionHelper(); + InitJsonHelper(); + + Utility.Converter.ScreenDpi = Screen.dpi; + if (Utility.Converter.ScreenDpi <= 0) + { + Utility.Converter.ScreenDpi = DefaultDpi; + } + + m_EditorResourceMode &= Application.isEditor; + if (m_EditorResourceMode) + { + Log.Info("During this run, Game Framework will use editor resource files, which you should validate first."); + } + + Application.targetFrameRate = m_FrameRate; + Time.timeScale = m_GameSpeed; + Application.runInBackground = m_RunInBackground; + Screen.sleepTimeout = m_NeverSleep ? SleepTimeout.NeverSleep : SleepTimeout.SystemSetting; +#else + Log.Error("Game Framework only applies with Unity 5.3 and above, but current Unity version is {0}.", Application.unityVersion); + GameEntry.Shutdown(ShutdownType.Quit); +#endif +#if UNITY_5_6_OR_NEWER + Application.lowMemory += OnLowMemory; +#endif + } + + private void Start() + { + } + + private void Update() + { + GameFrameworkEntry.Update(Time.deltaTime, Time.unscaledDeltaTime); + } + + private void OnApplicationQuit() + { +#if UNITY_5_6_OR_NEWER + Application.lowMemory -= OnLowMemory; +#endif + StopAllCoroutines(); + } + + private void OnDestroy() + { + GameFrameworkEntry.Shutdown(); + } + + /// + /// 暂停游戏。 + /// + public void PauseGame() + { + if (IsGamePaused) + { + return; + } + + m_GameSpeedBeforePause = GameSpeed; + GameSpeed = 0f; + } + + /// + /// 恢复游戏。 + /// + public void ResumeGame() + { + if (!IsGamePaused) + { + return; + } + + GameSpeed = m_GameSpeedBeforePause; + } + + /// + /// 重置为正常游戏速度。 + /// + public void ResetNormalGameSpeed() + { + if (IsNormalGameSpeed) + { + return; + } + + GameSpeed = 1f; + } + + internal void Shutdown() + { + Destroy(gameObject); + } + + private void InitTextHelper() + { + if (string.IsNullOrEmpty(m_TextHelperTypeName)) + { + return; + } + + Type textHelperType = Utility.Assembly.GetType(m_TextHelperTypeName); + if (textHelperType == null) + { + Log.Error("Can not find text helper type '{0}'.", m_TextHelperTypeName); + return; + } + + Utility.Text.ITextHelper textHelper = (Utility.Text.ITextHelper)Activator.CreateInstance(textHelperType); + if (textHelper == null) + { + Log.Error("Can not create text helper instance '{0}'.", m_TextHelperTypeName); + return; + } + + Utility.Text.SetTextHelper(textHelper); + } + + private void InitVersionHelper() + { + if (string.IsNullOrEmpty(m_VersionHelperTypeName)) + { + return; + } + + Type versionHelperType = Utility.Assembly.GetType(m_VersionHelperTypeName); + if (versionHelperType == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find version helper type '{0}'.", m_VersionHelperTypeName)); + } + + GameFramework.Version.IVersionHelper versionHelper = (GameFramework.Version.IVersionHelper)Activator.CreateInstance(versionHelperType); + if (versionHelper == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not create version helper instance '{0}'.", m_VersionHelperTypeName)); + } + + GameFramework.Version.SetVersionHelper(versionHelper); + } + + private void InitLogHelper() + { + if (string.IsNullOrEmpty(m_LogHelperTypeName)) + { + return; + } + + Type logHelperType = Utility.Assembly.GetType(m_LogHelperTypeName); + if (logHelperType == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not find log helper type '{0}'.", m_LogHelperTypeName)); + } + + GameFrameworkLog.ILogHelper logHelper = (GameFrameworkLog.ILogHelper)Activator.CreateInstance(logHelperType); + if (logHelper == null) + { + throw new GameFrameworkException(Utility.Text.Format("Can not create log helper instance '{0}'.", m_LogHelperTypeName)); + } + + GameFrameworkLog.SetLogHelper(logHelper); + } + + private void InitCompressionHelper() + { + if (string.IsNullOrEmpty(m_CompressionHelperTypeName)) + { + return; + } + + Type compressionHelperType = Utility.Assembly.GetType(m_CompressionHelperTypeName); + if (compressionHelperType == null) + { + Log.Error("Can not find compression helper type '{0}'.", m_CompressionHelperTypeName); + return; + } + + Utility.Compression.ICompressionHelper compressionHelper = (Utility.Compression.ICompressionHelper)Activator.CreateInstance(compressionHelperType); + if (compressionHelper == null) + { + Log.Error("Can not create compression helper instance '{0}'.", m_CompressionHelperTypeName); + return; + } + + Utility.Compression.SetCompressionHelper(compressionHelper); + } + + private void InitJsonHelper() + { + if (string.IsNullOrEmpty(m_JsonHelperTypeName)) + { + return; + } + + Type jsonHelperType = Utility.Assembly.GetType(m_JsonHelperTypeName); + if (jsonHelperType == null) + { + Log.Error("Can not find JSON helper type '{0}'.", m_JsonHelperTypeName); + return; + } + + Utility.Json.IJsonHelper jsonHelper = (Utility.Json.IJsonHelper)Activator.CreateInstance(jsonHelperType); + if (jsonHelper == null) + { + Log.Error("Can not create JSON helper instance '{0}'.", m_JsonHelperTypeName); + return; + } + + Utility.Json.SetJsonHelper(jsonHelper); + } + + private void OnLowMemory() + { + Log.Info("Low memory reported..."); + + ObjectPoolComponent objectPoolComponent = GameEntry.GetComponent(); + if (objectPoolComponent != null) + { + objectPoolComponent.ReleaseAllUnused(); + } + + ResourceComponent resourceCompoent = GameEntry.GetComponent(); + if (resourceCompoent != null) + { + resourceCompoent.ForceUnloadUnusedAssets(true); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/BaseComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/BaseComponent.cs.meta new file mode 100644 index 0000000..bbc27ae --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/BaseComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f98acd7d3bd2bf54dadf9644f60e5cb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameEntry.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameEntry.cs new file mode 100644 index 0000000..81f3a7b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameEntry.cs @@ -0,0 +1,150 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace UnityGameFramework.Runtime +{ + /// + /// 游戏入口。 + /// + public static class GameEntry + { + private static readonly GameFrameworkLinkedList s_GameFrameworkComponents = new GameFrameworkLinkedList(); + + /// + /// 游戏框架所在的场景编号。 + /// + internal const int GameFrameworkSceneId = 0; + + /// + /// 获取游戏框架组件。 + /// + /// 要获取的游戏框架组件类型。 + /// 要获取的游戏框架组件。 + public static T GetComponent() where T : GameFrameworkComponent + { + return (T)GetComponent(typeof(T)); + } + + /// + /// 获取游戏框架组件。 + /// + /// 要获取的游戏框架组件类型。 + /// 要获取的游戏框架组件。 + public static GameFrameworkComponent GetComponent(Type type) + { + LinkedListNode current = s_GameFrameworkComponents.First; + while (current != null) + { + if (current.Value.GetType() == type) + { + return current.Value; + } + + current = current.Next; + } + + return null; + } + + /// + /// 获取游戏框架组件。 + /// + /// 要获取的游戏框架组件类型名称。 + /// 要获取的游戏框架组件。 + public static GameFrameworkComponent GetComponent(string typeName) + { + LinkedListNode current = s_GameFrameworkComponents.First; + while (current != null) + { + Type type = current.Value.GetType(); + if (type.FullName == typeName || type.Name == typeName) + { + return current.Value; + } + + current = current.Next; + } + + return null; + } + + /// + /// 关闭游戏框架。 + /// + /// 关闭游戏框架类型。 + public static void Shutdown(ShutdownType shutdownType) + { + Log.Info("Shutdown Game Framework ({0})...", shutdownType); + BaseComponent baseComponent = GetComponent(); + if (baseComponent != null) + { + baseComponent.Shutdown(); + baseComponent = null; + } + + s_GameFrameworkComponents.Clear(); + + if (shutdownType == ShutdownType.None) + { + return; + } + + if (shutdownType == ShutdownType.Restart) + { + SceneManager.LoadScene(GameFrameworkSceneId); + return; + } + + if (shutdownType == ShutdownType.Quit) + { + Application.Quit(); +#if UNITY_EDITOR + UnityEditor.EditorApplication.isPlaying = false; +#endif + return; + } + } + + /// + /// 注册游戏框架组件。 + /// + /// 要注册的游戏框架组件。 + internal static void RegisterComponent(GameFrameworkComponent gameFrameworkComponent) + { + //如果组件为空返回 + if (gameFrameworkComponent == null) + { + Log.Error("Game Framework component is invalid."); + return; + } + //获取组件类型 + Type type = gameFrameworkComponent.GetType(); + //获取链表第一个节点 + LinkedListNode current = s_GameFrameworkComponents.First; + //如果节点不为空 + while (current != null) + { + //如果类型相等返回 + if (current.Value.GetType() == type) + { + Log.Error("Game Framework component type '{0}' is already exist.", type.FullName); + return; + } + + current = current.Next; + } + //将组件类型加入链表 + s_GameFrameworkComponents.AddLast(gameFrameworkComponent); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameEntry.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameEntry.cs.meta new file mode 100644 index 0000000..8c6d5f1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd346220e820e384b816477cdf1e1bb2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameFrameworkComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameFrameworkComponent.cs new file mode 100644 index 0000000..440a0c0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameFrameworkComponent.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 游戏框架组件抽象类。 + /// + public abstract class GameFrameworkComponent : MonoBehaviour + { + /// + /// 游戏框架组件初始化。 + /// + protected virtual void Awake() + { + GameEntry.RegisterComponent(this); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameFrameworkComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameFrameworkComponent.cs.meta new file mode 100644 index 0000000..2886464 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/GameFrameworkComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbf5faef1b7b7d24c8375006438a0cd0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/ShutdownType.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/ShutdownType.cs new file mode 100644 index 0000000..9d7b5d6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/ShutdownType.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + /// + /// 关闭游戏框架类型。 + /// + public enum ShutdownType : byte + { + /// + /// 仅关闭游戏框架。 + /// + None = 0, + + /// + /// 关闭游戏框架并重启游戏。 + /// + Restart, + + /// + /// 关闭游戏框架并退出游戏。 + /// + Quit, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/ShutdownType.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/ShutdownType.cs.meta new file mode 100644 index 0000000..1e1b91d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Base/ShutdownType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e19747752388e14bbe312e0f4c44e00 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config.meta new file mode 100644 index 0000000..c034904 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ff4afea74c892e04e984aa34aa089b89 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigComponent.cs new file mode 100644 index 0000000..cf053b4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigComponent.cs @@ -0,0 +1,408 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Config; +using GameFramework.Resource; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 全局配置组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Config")] + public sealed class ConfigComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + + private IConfigManager m_ConfigManager = null; + private EventComponent m_EventComponent = null; + + [SerializeField] + private bool m_EnableLoadConfigUpdateEvent = false; + + [SerializeField] + private bool m_EnableLoadConfigDependencyAssetEvent = false; + + [SerializeField] + private string m_ConfigHelperTypeName = "UnityGameFramework.Runtime.DefaultConfigHelper"; + + [SerializeField] + private ConfigHelperBase m_CustomConfigHelper = null; + + [SerializeField] + private int m_CachedBytesSize = 0; + + /// + /// 获取全局配置项数量。 + /// + public int Count + { + get + { + return m_ConfigManager.Count; + } + } + + /// + /// 获取缓冲二进制流的大小。 + /// + public int CachedBytesSize + { + get + { + return m_ConfigManager.CachedBytesSize; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_ConfigManager = GameFrameworkEntry.GetModule(); + if (m_ConfigManager == null) + { + Log.Fatal("Config manager is invalid."); + return; + } + + m_ConfigManager.ReadDataSuccess += OnReadDataSuccess; + m_ConfigManager.ReadDataFailure += OnReadDataFailure; + + if (m_EnableLoadConfigUpdateEvent) + { + m_ConfigManager.ReadDataUpdate += OnReadDataUpdate; + } + + if (m_EnableLoadConfigDependencyAssetEvent) + { + m_ConfigManager.ReadDataDependencyAsset += OnReadDataDependencyAsset; + } + } + + private void Start() + { + BaseComponent baseComponent = GameEntry.GetComponent(); + if (baseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (baseComponent.EditorResourceMode) + { + m_ConfigManager.SetResourceManager(baseComponent.EditorResourceHelper); + } + else + { + m_ConfigManager.SetResourceManager(GameFrameworkEntry.GetModule()); + } + + ConfigHelperBase configHelper = Helper.CreateHelper(m_ConfigHelperTypeName, m_CustomConfigHelper); + if (configHelper == null) + { + Log.Error("Can not create config helper."); + return; + } + + configHelper.name = "Config Helper"; + Transform transform = configHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_ConfigManager.SetDataProviderHelper(configHelper); + m_ConfigManager.SetConfigHelper(configHelper); + if (m_CachedBytesSize > 0) + { + EnsureCachedBytesSize(m_CachedBytesSize); + } + } + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + public void EnsureCachedBytesSize(int ensureSize) + { + m_ConfigManager.EnsureCachedBytesSize(ensureSize); + } + + /// + /// 释放缓存的二进制流。 + /// + public void FreeCachedBytes() + { + m_ConfigManager.FreeCachedBytes(); + } + + /// + /// 读取全局配置。 + /// + /// 全局配置资源名称。 + public void ReadData(string configAssetName) + { + m_ConfigManager.ReadData(configAssetName); + } + + /// + /// 读取全局配置。 + /// + /// 全局配置资源名称。 + /// 加载全局配置资源的优先级。 + public void ReadData(string configAssetName, int priority) + { + m_ConfigManager.ReadData(configAssetName, priority); + } + + /// + /// 读取全局配置。 + /// + /// 全局配置资源名称。 + /// 用户自定义数据。 + public void ReadData(string configAssetName, object userData) + { + m_ConfigManager.ReadData(configAssetName, userData); + } + + /// + /// 读取全局配置。 + /// + /// 全局配置资源名称。 + /// 加载全局配置资源的优先级。 + /// 用户自定义数据。 + public void ReadData(string configAssetName, int priority, object userData) + { + m_ConfigManager.ReadData(configAssetName, priority, userData); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置字符串。 + /// 是否解析全局配置成功。 + public bool ParseData(string configString) + { + return m_ConfigManager.ParseData(configString); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置字符串。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public bool ParseData(string configString, object userData) + { + return m_ConfigManager.ParseData(configString, userData); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置二进制流。 + /// 是否解析全局配置成功。 + public bool ParseData(byte[] configBytes) + { + return m_ConfigManager.ParseData(configBytes); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置二进制流。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public bool ParseData(byte[] configBytes, object userData) + { + return m_ConfigManager.ParseData(configBytes, userData); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置二进制流。 + /// 全局配置二进制流的起始位置。 + /// 全局配置二进制流的长度。 + /// 是否解析全局配置成功。 + public bool ParseData(byte[] configBytes, int startIndex, int length) + { + return m_ConfigManager.ParseData(configBytes, startIndex, length); + } + + /// + /// 解析全局配置。 + /// + /// 要解析的全局配置二进制流。 + /// 全局配置二进制流的起始位置。 + /// 全局配置二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public bool ParseData(byte[] configBytes, int startIndex, int length, object userData) + { + return m_ConfigManager.ParseData(configBytes, startIndex, length, userData); + } + + /// + /// 检查是否存在指定全局配置项。 + /// + /// 要检查全局配置项的名称。 + /// 指定的全局配置项是否存在。 + public bool HasConfig(string configName) + { + return m_ConfigManager.HasConfig(configName); + } + + /// + /// 从指定全局配置项中读取布尔值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的布尔值。 + public bool GetBool(string configName) + { + return m_ConfigManager.GetBool(configName); + } + + /// + /// 从指定全局配置项中读取布尔值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + public bool GetBool(string configName, bool defaultValue) + { + return m_ConfigManager.GetBool(configName, defaultValue); + } + + /// + /// 从指定全局配置项中读取整数值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的整数值。 + public int GetInt(string configName) + { + return m_ConfigManager.GetInt(configName); + } + + /// + /// 从指定全局配置项中读取整数值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的整数值。 + public int GetInt(string configName, int defaultValue) + { + return m_ConfigManager.GetInt(configName, defaultValue); + } + + /// + /// 从指定全局配置项中读取浮点数值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的浮点数值。 + public float GetFloat(string configName) + { + return m_ConfigManager.GetFloat(configName); + } + + /// + /// 从指定全局配置项中读取浮点数值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + public float GetFloat(string configName, float defaultValue) + { + return m_ConfigManager.GetFloat(configName, defaultValue); + } + + /// + /// 从指定全局配置项中读取字符串值。 + /// + /// 要获取全局配置项的名称。 + /// 读取的字符串值。 + public string GetString(string configName) + { + return m_ConfigManager.GetString(configName); + } + + /// + /// 从指定全局配置项中读取字符串值。 + /// + /// 要获取全局配置项的名称。 + /// 当指定的全局配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + public string GetString(string configName, string defaultValue) + { + return m_ConfigManager.GetString(configName, defaultValue); + } + + /// + /// 增加指定全局配置项。 + /// + /// 要增加全局配置项的名称。 + /// 全局配置项布尔值。 + /// 全局配置项整数值。 + /// 全局配置项浮点数值。 + /// 全局配置项字符串值。 + /// 是否增加全局配置项成功。 + public bool AddConfig(string configName, bool boolValue, int intValue, float floatValue, string stringValue) + { + return m_ConfigManager.AddConfig(configName, boolValue, intValue, floatValue, stringValue); + } + + /// + /// 移除指定全局配置项。 + /// + /// 要移除全局配置项的名称。 + /// 是否移除全局配置项成功。 + public bool RemoveConfig(string configName) + { + return m_ConfigManager.RemoveConfig(configName); + } + + /// + /// 清空所有全局配置项。 + /// + public void RemoveAllConfigs() + { + m_ConfigManager.RemoveAllConfigs(); + } + + private void OnReadDataSuccess(object sender, ReadDataSuccessEventArgs e) + { + m_EventComponent.Fire(this, LoadConfigSuccessEventArgs.Create(e)); + } + + private void OnReadDataFailure(object sender, ReadDataFailureEventArgs e) + { + Log.Warning("Load config failure, asset name '{0}', error message '{1}'.", e.DataAssetName, e.ErrorMessage); + m_EventComponent.Fire(this, LoadConfigFailureEventArgs.Create(e)); + } + + private void OnReadDataUpdate(object sender, ReadDataUpdateEventArgs e) + { + m_EventComponent.Fire(this, LoadConfigUpdateEventArgs.Create(e)); + } + + private void OnReadDataDependencyAsset(object sender, ReadDataDependencyAssetEventArgs e) + { + m_EventComponent.Fire(this, LoadConfigDependencyAssetEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigComponent.cs.meta new file mode 100644 index 0000000..9f3efe1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e847b2b3e22e9b4792ca7ea6e1714c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigHelperBase.cs new file mode 100644 index 0000000..a4ddd9c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigHelperBase.cs @@ -0,0 +1,68 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Config; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 全局配置辅助器基类。 + /// + public abstract class ConfigHelperBase : MonoBehaviour, IDataProviderHelper, IConfigHelper + { + /// + /// 读取全局配置。 + /// + /// 全局配置管理器。 + /// 全局配置资源名称。 + /// 全局配置资源。 + /// 用户自定义数据。 + /// 是否读取全局配置成功。 + public abstract bool ReadData(IConfigManager configManager, string configAssetName, object configAsset, object userData); + + /// + /// 读取全局配置。 + /// + /// 全局配置管理器。 + /// 全局配置资源名称。 + /// 全局配置二进制流。 + /// 全局配置二进制流的起始位置。 + /// 全局配置二进制流的长度。 + /// 用户自定义数据。 + /// 是否读取全局配置成功。 + public abstract bool ReadData(IConfigManager configManager, string configAssetName, byte[] configBytes, int startIndex, int length, object userData); + + /// + /// 解析全局配置。 + /// + /// 全局配置管理器。 + /// 要解析的全局配置字符串。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public abstract bool ParseData(IConfigManager configManager, string configString, object userData); + + /// + /// 解析全局配置。 + /// + /// 全局配置管理器。 + /// 要解析的全局配置二进制流。 + /// 全局配置二进制流的起始位置。 + /// 全局配置二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public abstract bool ParseData(IConfigManager configManager, byte[] configBytes, int startIndex, int length, object userData); + + /// + /// 释放全局配置资源。 + /// + /// 全局配置管理器。 + /// 要释放的全局配置资源。 + public abstract void ReleaseDataAsset(IConfigManager configManager, object configAsset); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigHelperBase.cs.meta new file mode 100644 index 0000000..c1dc18c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/ConfigHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5588940f3b356ec4b9cee3c5b4a905f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/DefaultConfigHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/DefaultConfigHelper.cs new file mode 100644 index 0000000..f4c9271 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/DefaultConfigHelper.cs @@ -0,0 +1,181 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Config; +using System; +using System.IO; +using System.Text; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认全局配置辅助器。 + /// + public class DefaultConfigHelper : ConfigHelperBase + { + private static readonly string[] ColumnSplitSeparator = new string[] { "\t" }; + private static readonly string BytesAssetExtension = ".bytes"; + private const int ColumnCount = 4; + + private ResourceComponent m_ResourceComponent = null; + + /// + /// 读取全局配置。 + /// + /// 全局配置管理器。 + /// 全局配置资源名称。 + /// 全局配置资源。 + /// 用户自定义数据。 + /// 是否读取全局配置成功。 + public override bool ReadData(IConfigManager configManager, string configAssetName, object configAsset, object userData) + { + TextAsset configTextAsset = configAsset as TextAsset; + if (configTextAsset != null) + { + if (configAssetName.EndsWith(BytesAssetExtension, StringComparison.Ordinal)) + { + return configManager.ParseData(configTextAsset.bytes, userData); + } + else + { + return configManager.ParseData(configTextAsset.text, userData); + } + } + + Log.Warning("Config asset '{0}' is invalid.", configAssetName); + return false; + } + + /// + /// 读取全局配置。 + /// + /// 全局配置管理器。 + /// 全局配置资源名称。 + /// 全局配置二进制流。 + /// 全局配置二进制流的起始位置。 + /// 全局配置二进制流的长度。 + /// 用户自定义数据。 + /// 是否读取全局配置成功。 + public override bool ReadData(IConfigManager configManager, string configAssetName, byte[] configBytes, int startIndex, int length, object userData) + { + if (configAssetName.EndsWith(BytesAssetExtension, StringComparison.Ordinal)) + { + return configManager.ParseData(configBytes, startIndex, length, userData); + } + else + { + return configManager.ParseData(Utility.Converter.GetString(configBytes, startIndex, length), userData); + } + } + + /// + /// 解析全局配置。 + /// + /// 全局配置管理器。 + /// 要解析的全局配置字符串。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public override bool ParseData(IConfigManager configManager, string configString, object userData) + { + try + { + int position = 0; + string configLineString = null; + while ((configLineString = configString.ReadLine(ref position)) != null) + { + if (configLineString[0] == '#') + { + continue; + } + + string[] splitedLine = configLineString.Split(ColumnSplitSeparator, StringSplitOptions.None); + if (splitedLine.Length != ColumnCount) + { + Log.Warning("Can not parse config line string '{0}' which column count is invalid.", configLineString); + return false; + } + + string configName = splitedLine[1]; + string configValue = splitedLine[3]; + if (!configManager.AddConfig(configName, configValue)) + { + Log.Warning("Can not add config with config name '{0}' which may be invalid or duplicate.", configName); + return false; + } + } + + return true; + } + catch (Exception exception) + { + Log.Warning("Can not parse config string with exception '{0}'.", exception); + return false; + } + } + + /// + /// 解析全局配置。 + /// + /// 全局配置管理器。 + /// 要解析的全局配置二进制流。 + /// 全局配置二进制流的起始位置。 + /// 全局配置二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析全局配置成功。 + public override bool ParseData(IConfigManager configManager, byte[] configBytes, int startIndex, int length, object userData) + { + try + { + using (MemoryStream memoryStream = new MemoryStream(configBytes, startIndex, length, false)) + { + using (BinaryReader binaryReader = new BinaryReader(memoryStream, Encoding.UTF8)) + { + while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) + { + string configName = binaryReader.ReadString(); + string configValue = binaryReader.ReadString(); + if (!configManager.AddConfig(configName, configValue)) + { + Log.Warning("Can not add config with config name '{0}' which may be invalid or duplicate.", configName); + return false; + } + } + } + } + + return true; + } + catch (Exception exception) + { + Log.Warning("Can not parse config bytes with exception '{0}'.", exception); + return false; + } + } + + /// + /// 释放全局配置资源。 + /// + /// 全局配置管理器。 + /// 要释放的全局配置资源。 + public override void ReleaseDataAsset(IConfigManager configManager, object configAsset) + { + m_ResourceComponent.UnloadAsset(configAsset); + } + + private void Start() + { + m_ResourceComponent = GameEntry.GetComponent(); + if (m_ResourceComponent == null) + { + Log.Fatal("Resource component is invalid."); + return; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/DefaultConfigHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/DefaultConfigHelper.cs.meta new file mode 100644 index 0000000..ae700fa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/DefaultConfigHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c039b1ea5c75e24fa12a58ab3227ab7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigDependencyAssetEventArgs.cs new file mode 100644 index 0000000..b45f4a6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigDependencyAssetEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载全局配置时加载依赖资源事件。 + /// + public sealed class LoadConfigDependencyAssetEventArgs : GameEventArgs + { + /// + /// 加载全局配置失败事件编号。 + /// + public static readonly int EventId = typeof(LoadConfigDependencyAssetEventArgs).GetHashCode(); + + /// + /// 初始化加载全局配置时加载依赖资源事件的新实例。 + /// + public LoadConfigDependencyAssetEventArgs() + { + ConfigAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取加载全局配置失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取全局配置资源名称。 + /// + public string ConfigAssetName + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载全局配置时加载依赖资源事件。 + /// + /// 内部事件。 + /// 创建的加载全局配置时加载依赖资源事件。 + public static LoadConfigDependencyAssetEventArgs Create(ReadDataDependencyAssetEventArgs e) + { + LoadConfigDependencyAssetEventArgs loadConfigDependencyAssetEventArgs = ReferencePool.Acquire(); + loadConfigDependencyAssetEventArgs.ConfigAssetName = e.DataAssetName; + loadConfigDependencyAssetEventArgs.DependencyAssetName = e.DependencyAssetName; + loadConfigDependencyAssetEventArgs.LoadedCount = e.LoadedCount; + loadConfigDependencyAssetEventArgs.TotalCount = e.TotalCount; + loadConfigDependencyAssetEventArgs.UserData = e.UserData; + return loadConfigDependencyAssetEventArgs; + } + + /// + /// 清理加载全局配置时加载依赖资源事件。 + /// + public override void Clear() + { + ConfigAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..ebe3079 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 224a6c56bac19dc47b5a08f772e59af1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigFailureEventArgs.cs new file mode 100644 index 0000000..1fb51eb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigFailureEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载全局配置失败事件。 + /// + public sealed class LoadConfigFailureEventArgs : GameEventArgs + { + /// + /// 加载全局配置失败事件编号。 + /// + public static readonly int EventId = typeof(LoadConfigFailureEventArgs).GetHashCode(); + + /// + /// 初始化加载全局配置失败事件的新实例。 + /// + public LoadConfigFailureEventArgs() + { + ConfigAssetName = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取加载全局配置失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取全局配置资源名称。 + /// + public string ConfigAssetName + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载全局配置失败事件。 + /// + /// 内部事件。 + /// 创建的加载全局配置失败事件。 + public static LoadConfigFailureEventArgs Create(ReadDataFailureEventArgs e) + { + LoadConfigFailureEventArgs loadConfigFailureEventArgs = ReferencePool.Acquire(); + loadConfigFailureEventArgs.ConfigAssetName = e.DataAssetName; + loadConfigFailureEventArgs.ErrorMessage = e.ErrorMessage; + loadConfigFailureEventArgs.UserData = e.UserData; + return loadConfigFailureEventArgs; + } + + /// + /// 清理加载全局配置失败事件。 + /// + public override void Clear() + { + ConfigAssetName = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigFailureEventArgs.cs.meta new file mode 100644 index 0000000..650ab48 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca7b842aaf795c6428b7a23287dec802 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigSuccessEventArgs.cs new file mode 100644 index 0000000..afbedde --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigSuccessEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载全局配置成功事件。 + /// + public sealed class LoadConfigSuccessEventArgs : GameEventArgs + { + /// + /// 加载全局配置成功事件编号。 + /// + public static readonly int EventId = typeof(LoadConfigSuccessEventArgs).GetHashCode(); + + /// + /// 初始化加载全局配置成功事件编号的新实例。 + /// + public LoadConfigSuccessEventArgs() + { + ConfigAssetName = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取加载全局配置成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取全局配置资源名称。 + /// + public string ConfigAssetName + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载全局配置成功事件。 + /// + /// 内部事件。 + /// 创建的加载全局配置成功事件。 + public static LoadConfigSuccessEventArgs Create(ReadDataSuccessEventArgs e) + { + LoadConfigSuccessEventArgs loadConfigSuccessEventArgs = ReferencePool.Acquire(); + loadConfigSuccessEventArgs.ConfigAssetName = e.DataAssetName; + loadConfigSuccessEventArgs.Duration = e.Duration; + loadConfigSuccessEventArgs.UserData = e.UserData; + return loadConfigSuccessEventArgs; + } + + /// + /// 清理加载全局配置成功事件。 + /// + public override void Clear() + { + ConfigAssetName = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigSuccessEventArgs.cs.meta new file mode 100644 index 0000000..9e82ac2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8edee6cdf050d4f47ac48581f944d4ae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigUpdateEventArgs.cs new file mode 100644 index 0000000..808aa30 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigUpdateEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载全局配置更新事件。 + /// + public sealed class LoadConfigUpdateEventArgs : GameEventArgs + { + /// + /// 加载全局配置失败事件编号。 + /// + public static readonly int EventId = typeof(LoadConfigUpdateEventArgs).GetHashCode(); + + /// + /// 初始化加载全局配置更新事件的新实例。 + /// + public LoadConfigUpdateEventArgs() + { + ConfigAssetName = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取加载全局配置失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取全局配置资源名称。 + /// + public string ConfigAssetName + { + get; + private set; + } + + /// + /// 获取加载全局配置进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载全局配置更新事件。 + /// + /// 内部事件。 + /// 创建的加载全局配置更新事件。 + public static LoadConfigUpdateEventArgs Create(ReadDataUpdateEventArgs e) + { + LoadConfigUpdateEventArgs loadConfigUpdateEventArgs = ReferencePool.Acquire(); + loadConfigUpdateEventArgs.ConfigAssetName = e.DataAssetName; + loadConfigUpdateEventArgs.Progress = e.Progress; + loadConfigUpdateEventArgs.UserData = e.UserData; + return loadConfigUpdateEventArgs; + } + + /// + /// 清理加载全局配置更新事件。 + /// + public override void Clear() + { + ConfigAssetName = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigUpdateEventArgs.cs.meta new file mode 100644 index 0000000..2efb530 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Config/LoadConfigUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07c976efcbda2464bb7ef36e80504f3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode.meta new file mode 100644 index 0000000..7bf2e7e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f919642531f20564094b12cd52df111d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode/DataNodeComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode/DataNodeComponent.cs new file mode 100644 index 0000000..1ec03e8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode/DataNodeComponent.cs @@ -0,0 +1,210 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.DataNode; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 数据结点组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Data Node")] + public sealed class DataNodeComponent : GameFrameworkComponent + { + private IDataNodeManager m_DataNodeManager = null; + + /// + /// 获取根数据结点。 + /// + public IDataNode Root + { + get + { + return m_DataNodeManager.Root; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_DataNodeManager = GameFrameworkEntry.GetModule(); + if (m_DataNodeManager == null) + { + Log.Fatal("Data node manager is invalid."); + return; + } + } + + private void Start() + { + } + + /// + /// 根据类型获取数据结点的数据。 + /// + /// 要获取的数据类型。 + /// 相对于 node 的查找路径。 + /// 指定类型的数据。 + public T GetData(string path) where T : Variable + { + return m_DataNodeManager.GetData(path); + } + + /// + /// 获取数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 数据结点的数据。 + public Variable GetData(string path) + { + return m_DataNodeManager.GetData(path); + } + + /// + /// 根据类型获取数据结点的数据。 + /// + /// 要获取的数据类型。 + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定类型的数据。 + public T GetData(string path, IDataNode node) where T : Variable + { + return m_DataNodeManager.GetData(path, node); + } + + /// + /// 获取数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 数据结点的数据。 + public Variable GetData(string path, IDataNode node) + { + return m_DataNodeManager.GetData(path, node); + } + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据类型。 + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + public void SetData(string path, T data) where T : Variable + { + m_DataNodeManager.SetData(path, data); + } + + /// + /// 设置数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + public void SetData(string path, Variable data) + { + m_DataNodeManager.SetData(path, data); + } + + /// + /// 设置数据结点的数据。 + /// + /// 要设置的数据类型。 + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + /// 查找起始结点。 + public void SetData(string path, T data, IDataNode node) where T : Variable + { + m_DataNodeManager.SetData(path, data, node); + } + + /// + /// 设置数据结点的数据。 + /// + /// 相对于 node 的查找路径。 + /// 要设置的数据。 + /// 查找起始结点。 + public void SetData(string path, Variable data, IDataNode node) + { + m_DataNodeManager.SetData(path, data, node); + } + + /// + /// 获取数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 指定位置的数据结点,如果没有找到,则返回空。 + public IDataNode GetNode(string path) + { + return m_DataNodeManager.GetNode(path); + } + + /// + /// 获取数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定位置的数据结点,如果没有找到,则返回空。 + public IDataNode GetNode(string path, IDataNode node) + { + return m_DataNodeManager.GetNode(path, node); + } + + /// + /// 获取或增加数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 指定位置的数据结点,如果没有找到,则增加相应的数据结点。 + public IDataNode GetOrAddNode(string path) + { + return m_DataNodeManager.GetOrAddNode(path); + } + + /// + /// 获取或增加数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + /// 指定位置的数据结点,如果没有找到,则增加相应的数据结点。 + public IDataNode GetOrAddNode(string path, IDataNode node) + { + return m_DataNodeManager.GetOrAddNode(path, node); + } + + /// + /// 移除数据结点。 + /// + /// 相对于 node 的查找路径。 + public void RemoveNode(string path) + { + m_DataNodeManager.RemoveNode(path); + } + + /// + /// 移除数据结点。 + /// + /// 相对于 node 的查找路径。 + /// 查找起始结点。 + public void RemoveNode(string path, IDataNode node) + { + m_DataNodeManager.RemoveNode(path, node); + } + + /// + /// 移除所有数据结点。 + /// + public void Clear() + { + m_DataNodeManager.Clear(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode/DataNodeComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode/DataNodeComponent.cs.meta new file mode 100644 index 0000000..73d7da2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataNode/DataNodeComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67038fd9feefc894aa31ae3869a45b72 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable.meta new file mode 100644 index 0000000..84c817d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c37122151fcac7a4d82295f02039a322 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataRowBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataRowBase.cs new file mode 100644 index 0000000..2fc435f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataRowBase.cs @@ -0,0 +1,51 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.DataTable; + +namespace UnityGameFramework.Runtime +{ + /// + /// 数据表行基类。 + /// + public abstract class DataRowBase : IDataRow + { + /// + /// 获取数据表行的编号。 + /// + public abstract int Id + { + get; + } + + /// + /// 解析数据表行。 + /// + /// 要解析的数据表行字符串。 + /// 用户自定义数据。 + /// 是否解析数据表行成功。 + public virtual bool ParseDataRow(string dataRowString, object userData) + { + Log.Warning("Not implemented ParseDataRow(string dataRowString, object userData)."); + return false; + } + + /// + /// 解析数据表行。 + /// + /// 要解析的数据表行二进制流。 + /// 数据表行二进制流的起始位置。 + /// 数据表行二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析数据表行成功。 + public virtual bool ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData) + { + Log.Warning("Not implemented ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData)."); + return false; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataRowBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataRowBase.cs.meta new file mode 100644 index 0000000..83d9904 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataRowBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2e51f0c2dffb5748b75e474971bbe09 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableComponent.cs new file mode 100644 index 0000000..5ead536 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableComponent.cs @@ -0,0 +1,399 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.DataTable; +using GameFramework.Resource; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 数据表组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Data Table")] + public sealed class DataTableComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + + private IDataTableManager m_DataTableManager = null; + private EventComponent m_EventComponent = null; + + [SerializeField] + private bool m_EnableLoadDataTableUpdateEvent = false; + + [SerializeField] + private bool m_EnableLoadDataTableDependencyAssetEvent = false; + + [SerializeField] + private string m_DataTableHelperTypeName = "UnityGameFramework.Runtime.DefaultDataTableHelper"; + + [SerializeField] + private DataTableHelperBase m_CustomDataTableHelper = null; + + [SerializeField] + private int m_CachedBytesSize = 0; + + /// + /// 获取数据表数量。 + /// + public int Count + { + get + { + return m_DataTableManager.Count; + } + } + + /// + /// 获取缓冲二进制流的大小。 + /// + public int CachedBytesSize + { + get + { + return m_DataTableManager.CachedBytesSize; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_DataTableManager = GameFrameworkEntry.GetModule(); + if (m_DataTableManager == null) + { + Log.Fatal("Data table manager is invalid."); + return; + } + } + + private void Start() + { + BaseComponent baseComponent = GameEntry.GetComponent(); + if (baseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (baseComponent.EditorResourceMode) + { + m_DataTableManager.SetResourceManager(baseComponent.EditorResourceHelper); + } + else + { + m_DataTableManager.SetResourceManager(GameFrameworkEntry.GetModule()); + } + + DataTableHelperBase dataTableHelper = Helper.CreateHelper(m_DataTableHelperTypeName, m_CustomDataTableHelper); + if (dataTableHelper == null) + { + Log.Error("Can not create data table helper."); + return; + } + + dataTableHelper.name = "Data Table Helper"; + Transform transform = dataTableHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_DataTableManager.SetDataProviderHelper(dataTableHelper); + m_DataTableManager.SetDataTableHelper(dataTableHelper); + if (m_CachedBytesSize > 0) + { + EnsureCachedBytesSize(m_CachedBytesSize); + } + } + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + public void EnsureCachedBytesSize(int ensureSize) + { + m_DataTableManager.EnsureCachedBytesSize(ensureSize); + } + + /// + /// 释放缓存的二进制流。 + /// + public void FreeCachedBytes() + { + m_DataTableManager.FreeCachedBytes(); + } + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 是否存在数据表。 + public bool HasDataTable() where T : IDataRow + { + return m_DataTableManager.HasDataTable(); + } + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 是否存在数据表。 + public bool HasDataTable(Type dataRowType) + { + return m_DataTableManager.HasDataTable(dataRowType); + } + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否存在数据表。 + public bool HasDataTable(string name) where T : IDataRow + { + return m_DataTableManager.HasDataTable(name); + } + + /// + /// 是否存在数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否存在数据表。 + public bool HasDataTable(Type dataRowType, string name) + { + return m_DataTableManager.HasDataTable(dataRowType, name); + } + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 要获取的数据表。 + public IDataTable GetDataTable() where T : IDataRow + { + return m_DataTableManager.GetDataTable(); + } + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 要获取的数据表。 + public DataTableBase GetDataTable(Type dataRowType) + { + return m_DataTableManager.GetDataTable(dataRowType); + } + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要获取的数据表。 + public IDataTable GetDataTable(string name) where T : IDataRow + { + return m_DataTableManager.GetDataTable(name); + } + + /// + /// 获取数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要获取的数据表。 + public DataTableBase GetDataTable(Type dataRowType, string name) + { + return m_DataTableManager.GetDataTable(dataRowType, name); + } + + /// + /// 获取所有数据表。 + /// + public DataTableBase[] GetAllDataTables() + { + return m_DataTableManager.GetAllDataTables(); + } + + /// + /// 获取所有数据表。 + /// + /// 所有数据表。 + public void GetAllDataTables(List results) + { + m_DataTableManager.GetAllDataTables(results); + } + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 要创建的数据表。 + public IDataTable CreateDataTable() where T : class, IDataRow, new() + { + return CreateDataTable(null); + } + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 要创建的数据表。 + public DataTableBase CreateDataTable(Type dataRowType) + { + return CreateDataTable(dataRowType, null); + } + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要创建的数据表。 + public IDataTable CreateDataTable(string name) where T : class, IDataRow, new() + { + IDataTable dataTable = m_DataTableManager.CreateDataTable(name); + DataTableBase dataTableBase = (DataTableBase)dataTable; + dataTableBase.ReadDataSuccess += OnReadDataSuccess; + dataTableBase.ReadDataFailure += OnReadDataFailure; + + if (m_EnableLoadDataTableUpdateEvent) + { + dataTableBase.ReadDataUpdate += OnReadDataUpdate; + } + + if (m_EnableLoadDataTableDependencyAssetEvent) + { + dataTableBase.ReadDataDependencyAsset += OnReadDataDependencyAsset; + } + + return dataTable; + } + + /// + /// 创建数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 要创建的数据表。 + public DataTableBase CreateDataTable(Type dataRowType, string name) + { + DataTableBase dataTable = m_DataTableManager.CreateDataTable(dataRowType, name); + dataTable.ReadDataSuccess += OnReadDataSuccess; + dataTable.ReadDataFailure += OnReadDataFailure; + + if (m_EnableLoadDataTableUpdateEvent) + { + dataTable.ReadDataUpdate += OnReadDataUpdate; + } + + if (m_EnableLoadDataTableDependencyAssetEvent) + { + dataTable.ReadDataDependencyAsset += OnReadDataDependencyAsset; + } + + return dataTable; + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable() where T : IDataRow, new() + { + return m_DataTableManager.DestroyDataTable(); + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(Type dataRowType) + { + return m_DataTableManager.DestroyDataTable(dataRowType); + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(string name) where T : IDataRow + { + return m_DataTableManager.DestroyDataTable(name); + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 数据表名称。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(Type dataRowType, string name) + { + return m_DataTableManager.DestroyDataTable(dataRowType, name); + } + + /// + /// 销毁数据表。 + /// + /// 数据表行的类型。 + /// 要销毁的数据表。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(IDataTable dataTable) where T : IDataRow + { + return m_DataTableManager.DestroyDataTable(dataTable); + } + + /// + /// 销毁数据表。 + /// + /// 要销毁的数据表。 + /// 是否销毁数据表成功。 + public bool DestroyDataTable(DataTableBase dataTable) + { + return m_DataTableManager.DestroyDataTable(dataTable); + } + + private void OnReadDataSuccess(object sender, ReadDataSuccessEventArgs e) + { + m_EventComponent.Fire(this, LoadDataTableSuccessEventArgs.Create(e)); + } + + private void OnReadDataFailure(object sender, ReadDataFailureEventArgs e) + { + Log.Warning("Load data table failure, asset name '{0}', error message '{1}'.", e.DataAssetName, e.ErrorMessage); + m_EventComponent.Fire(this, LoadDataTableFailureEventArgs.Create(e)); + } + + private void OnReadDataUpdate(object sender, ReadDataUpdateEventArgs e) + { + m_EventComponent.Fire(this, LoadDataTableUpdateEventArgs.Create(e)); + } + + private void OnReadDataDependencyAsset(object sender, ReadDataDependencyAssetEventArgs e) + { + m_EventComponent.Fire(this, LoadDataTableDependencyAssetEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableComponent.cs.meta new file mode 100644 index 0000000..2e0e4c6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54066418ab853614483ea44b531049f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableHelperBase.cs new file mode 100644 index 0000000..43dd46d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableHelperBase.cs @@ -0,0 +1,68 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.DataTable; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 数据表辅助器基类。 + /// + public abstract class DataTableHelperBase : MonoBehaviour, IDataProviderHelper, IDataTableHelper + { + /// + /// 读取数据表。 + /// + /// 数据表。 + /// 数据表资源名称。 + /// 数据表资源。 + /// 用户自定义数据。 + /// 是否读取数据表成功。 + public abstract bool ReadData(DataTableBase dataTable, string dataTableAssetName, object dataTableAsset, object userData); + + /// + /// 读取数据表。 + /// + /// 数据表。 + /// 数据表资源名称。 + /// 数据表二进制流。 + /// 数据表二进制流的起始位置。 + /// 数据表二进制流的长度。 + /// 用户自定义数据。 + /// 是否读取数据表成功。 + public abstract bool ReadData(DataTableBase dataTable, string dataTableAssetName, byte[] dataTableBytes, int startIndex, int length, object userData); + + /// + /// 解析数据表。 + /// + /// 数据表。 + /// 要解析的数据表字符串。 + /// 用户自定义数据。 + /// 是否解析数据表成功。 + public abstract bool ParseData(DataTableBase dataTable, string dataTableString, object userData); + + /// + /// 解析数据表。 + /// + /// 数据表。 + /// 要解析的数据表二进制流。 + /// 数据表二进制流的起始位置。 + /// 数据表二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析数据表成功。 + public abstract bool ParseData(DataTableBase dataTable, byte[] dataTableBytes, int startIndex, int length, object userData); + + /// + /// 释放数据表资源。 + /// + /// 数据表。 + /// 要释放的数据表资源。 + public abstract void ReleaseDataAsset(DataTableBase dataTable, object dataTableAsset); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableHelperBase.cs.meta new file mode 100644 index 0000000..f66377e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DataTableHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c48521d647fac4408f41cca9820ec55 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DefaultDataTableHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DefaultDataTableHelper.cs new file mode 100644 index 0000000..3dd85d5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DefaultDataTableHelper.cs @@ -0,0 +1,171 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.DataTable; +using System; +using System.IO; +using System.Text; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认数据表辅助器。 + /// + public class DefaultDataTableHelper : DataTableHelperBase + { + private static readonly string BytesAssetExtension = ".bytes"; + + private ResourceComponent m_ResourceComponent = null; + + /// + /// 读取数据表。 + /// + /// 数据表。 + /// 数据表资源名称。 + /// 数据表资源。 + /// 用户自定义数据。 + /// 是否读取数据表成功。 + public override bool ReadData(DataTableBase dataTable, string dataTableAssetName, object dataTableAsset, object userData) + { + TextAsset dataTableTextAsset = dataTableAsset as TextAsset; + if (dataTableTextAsset != null) + { + if (dataTableAssetName.EndsWith(BytesAssetExtension, StringComparison.Ordinal)) + { + return dataTable.ParseData(dataTableTextAsset.bytes, userData); + } + else + { + return dataTable.ParseData(dataTableTextAsset.text, userData); + } + } + + Log.Warning("Data table asset '{0}' is invalid.", dataTableAssetName); + return false; + } + + /// + /// 读取数据表。 + /// + /// 数据表。 + /// 数据表资源名称。 + /// 数据表二进制流。 + /// 数据表二进制流的起始位置。 + /// 数据表二进制流的长度。 + /// 用户自定义数据。 + /// 是否读取数据表成功。 + public override bool ReadData(DataTableBase dataTable, string dataTableAssetName, byte[] dataTableBytes, int startIndex, int length, object userData) + { + if (dataTableAssetName.EndsWith(BytesAssetExtension, StringComparison.Ordinal)) + { + return dataTable.ParseData(dataTableBytes, startIndex, length, userData); + } + else + { + return dataTable.ParseData(Utility.Converter.GetString(dataTableBytes, startIndex, length), userData); + } + } + + /// + /// 解析数据表。 + /// + /// 数据表。 + /// 要解析的数据表字符串。 + /// 用户自定义数据。 + /// 是否解析数据表成功。 + public override bool ParseData(DataTableBase dataTable, string dataTableString, object userData) + { + try + { + int position = 0; + string dataRowString = null; + while ((dataRowString = dataTableString.ReadLine(ref position)) != null) + { + if (dataRowString[0] == '#') + { + continue; + } + + if (!dataTable.AddDataRow(dataRowString, userData)) + { + Log.Warning("Can not parse data row string '{0}'.", dataRowString); + return false; + } + } + + return true; + } + catch (Exception exception) + { + Log.Warning("Can not parse data table string with exception '{0}'.", exception); + return false; + } + } + + /// + /// 解析数据表。 + /// + /// 数据表。 + /// 要解析的数据表二进制流。 + /// 数据表二进制流的起始位置。 + /// 数据表二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析数据表成功。 + public override bool ParseData(DataTableBase dataTable, byte[] dataTableBytes, int startIndex, int length, object userData) + { + try + { + using (MemoryStream memoryStream = new MemoryStream(dataTableBytes, startIndex, length, false)) + { + using (BinaryReader binaryReader = new BinaryReader(memoryStream, Encoding.UTF8)) + { + while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) + { + int dataRowBytesLength = binaryReader.Read7BitEncodedInt32(); + if (!dataTable.AddDataRow(dataTableBytes, (int)binaryReader.BaseStream.Position, dataRowBytesLength, userData)) + { + Log.Warning("Can not parse data row bytes."); + return false; + } + + binaryReader.BaseStream.Position += dataRowBytesLength; + } + } + } + + return true; + } + catch (Exception exception) + { + Log.Warning("Can not parse dictionary bytes with exception '{0}'.", exception); + return false; + } + } + + /// + /// 释放数据表资源。 + /// + /// 数据表。 + /// 要释放的数据表资源。 + public override void ReleaseDataAsset(DataTableBase dataTable, object dataTableAsset) + { + m_ResourceComponent.UnloadAsset(dataTableAsset); + } + + private void Start() + { + m_ResourceComponent = GameEntry.GetComponent(); + if (m_ResourceComponent == null) + { + Log.Fatal("Resource component is invalid."); + return; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DefaultDataTableHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DefaultDataTableHelper.cs.meta new file mode 100644 index 0000000..536b3c6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/DefaultDataTableHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f6a52ac548bf3654a93c12610240a67d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableDependencyAssetEventArgs.cs new file mode 100644 index 0000000..7205de1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableDependencyAssetEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载数据表时加载依赖资源事件。 + /// + public sealed class LoadDataTableDependencyAssetEventArgs : GameEventArgs + { + /// + /// 加载数据表时加载依赖资源事件编号。 + /// + public static readonly int EventId = typeof(LoadDataTableDependencyAssetEventArgs).GetHashCode(); + + /// + /// 初始化加载数据表时加载依赖资源事件的新实例。 + /// + public LoadDataTableDependencyAssetEventArgs() + { + DataTableAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取加载数据表时加载依赖资源事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取数据表资源名称。 + /// + public string DataTableAssetName + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载数据表时加载依赖资源事件。 + /// + /// 内部事件。 + /// 创建的加载数据表时加载依赖资源事件。 + public static LoadDataTableDependencyAssetEventArgs Create(ReadDataDependencyAssetEventArgs e) + { + LoadDataTableDependencyAssetEventArgs loadDataTableDependencyAssetEventArgs = ReferencePool.Acquire(); + loadDataTableDependencyAssetEventArgs.DataTableAssetName = e.DataAssetName; + loadDataTableDependencyAssetEventArgs.DependencyAssetName = e.DependencyAssetName; + loadDataTableDependencyAssetEventArgs.LoadedCount = e.LoadedCount; + loadDataTableDependencyAssetEventArgs.TotalCount = e.TotalCount; + loadDataTableDependencyAssetEventArgs.UserData = e.UserData; + return loadDataTableDependencyAssetEventArgs; + } + + /// + /// 清理加载数据表时加载依赖资源事件。 + /// + public override void Clear() + { + DataTableAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..95e5ddc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d55700c511451364c85eca18f23c5e9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableFailureEventArgs.cs new file mode 100644 index 0000000..e8477f4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableFailureEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载数据表失败事件。 + /// + public sealed class LoadDataTableFailureEventArgs : GameEventArgs + { + /// + /// 加载数据表失败事件编号。 + /// + public static readonly int EventId = typeof(LoadDataTableFailureEventArgs).GetHashCode(); + + /// + /// 初始化加载数据表失败事件的新实例。 + /// + public LoadDataTableFailureEventArgs() + { + DataTableAssetName = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取加载数据表失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取数据表资源名称。 + /// + public string DataTableAssetName + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载数据表失败事件。 + /// + /// 内部事件。 + /// 创建的加载数据表失败事件。 + public static LoadDataTableFailureEventArgs Create(ReadDataFailureEventArgs e) + { + LoadDataTableFailureEventArgs loadDataTableFailureEventArgs = ReferencePool.Acquire(); + loadDataTableFailureEventArgs.DataTableAssetName = e.DataAssetName; + loadDataTableFailureEventArgs.ErrorMessage = e.ErrorMessage; + loadDataTableFailureEventArgs.UserData = e.UserData; + return loadDataTableFailureEventArgs; + } + + /// + /// 清理加载数据表失败事件。 + /// + public override void Clear() + { + DataTableAssetName = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableFailureEventArgs.cs.meta new file mode 100644 index 0000000..5bb41e6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7196ee8c6ea2e0c4ebd4825fe6c9dcd1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableSuccessEventArgs.cs new file mode 100644 index 0000000..7c6687b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableSuccessEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载数据表成功事件。 + /// + public sealed class LoadDataTableSuccessEventArgs : GameEventArgs + { + /// + /// 加载数据表成功事件编号。 + /// + public static readonly int EventId = typeof(LoadDataTableSuccessEventArgs).GetHashCode(); + + /// + /// 初始化加载数据表成功事件的新实例。 + /// + public LoadDataTableSuccessEventArgs() + { + DataTableAssetName = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取加载数据表成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取数据表资源名称。 + /// + public string DataTableAssetName + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载数据表成功事件。 + /// + /// 内部事件。 + /// 创建的加载数据表成功事件。 + public static LoadDataTableSuccessEventArgs Create(ReadDataSuccessEventArgs e) + { + LoadDataTableSuccessEventArgs loadDataTableSuccessEventArgs = ReferencePool.Acquire(); + loadDataTableSuccessEventArgs.DataTableAssetName = e.DataAssetName; + loadDataTableSuccessEventArgs.Duration = e.Duration; + loadDataTableSuccessEventArgs.UserData = e.UserData; + return loadDataTableSuccessEventArgs; + } + + /// + /// 清理加载数据表成功事件。 + /// + public override void Clear() + { + DataTableAssetName = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableSuccessEventArgs.cs.meta new file mode 100644 index 0000000..7c9f1e7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed41d1abe08b7754481956fece8dfba4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableUpdateEventArgs.cs new file mode 100644 index 0000000..0c65ac7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableUpdateEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载数据表更新事件。 + /// + public sealed class LoadDataTableUpdateEventArgs : GameEventArgs + { + /// + /// 加载数据表更新事件编号。 + /// + public static readonly int EventId = typeof(LoadDataTableUpdateEventArgs).GetHashCode(); + + /// + /// 初始化加载数据表更新事件的新实例。 + /// + public LoadDataTableUpdateEventArgs() + { + DataTableAssetName = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取加载数据表更新事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取数据表资源名称。 + /// + public string DataTableAssetName + { + get; + private set; + } + + /// + /// 获取加载数据表进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载数据表更新事件。 + /// + /// 内部事件。 + /// 创建的加载数据表更新事件。 + public static LoadDataTableUpdateEventArgs Create(ReadDataUpdateEventArgs e) + { + LoadDataTableUpdateEventArgs loadDataTableUpdateEventArgs = ReferencePool.Acquire(); + loadDataTableUpdateEventArgs.DataTableAssetName = e.DataAssetName; + loadDataTableUpdateEventArgs.Progress = e.Progress; + loadDataTableUpdateEventArgs.UserData = e.UserData; + return loadDataTableUpdateEventArgs; + } + + /// + /// 清理加载数据表更新事件。 + /// + public override void Clear() + { + DataTableAssetName = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableUpdateEventArgs.cs.meta new file mode 100644 index 0000000..9d35c4a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/DataTable/LoadDataTableUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35eba4a8a9ee9954392a0e99aa8111d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger.meta new file mode 100644 index 0000000..4f7afab --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eadd5c8c1a8797c45b1c8a9635f8cf52 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerActiveWindowType.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerActiveWindowType.cs new file mode 100644 index 0000000..2a5fa6d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerActiveWindowType.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + /// + /// 调试器激活窗口类型。 + /// + public enum DebuggerActiveWindowType : byte + { + /// + /// 总是打开。 + /// + AlwaysOpen = 0, + + /// + /// 仅在开发模式时打开。 + /// + OnlyOpenWhenDevelopment, + + /// + /// 仅在编辑器中打开。 + /// + OnlyOpenInEditor, + + /// + /// 总是关闭。 + /// + AlwaysClose, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerActiveWindowType.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerActiveWindowType.cs.meta new file mode 100644 index 0000000..b73d304 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerActiveWindowType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1baccfe5abb590428eb0322088bf4ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ConsoleWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ConsoleWindow.cs new file mode 100644 index 0000000..8b66cae --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ConsoleWindow.cs @@ -0,0 +1,509 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Debugger; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + [Serializable] + private sealed class ConsoleWindow : IDebuggerWindow + { + private readonly Queue m_LogNodes = new Queue(); + + private SettingComponent m_SettingComponent = null; + private Vector2 m_LogScrollPosition = Vector2.zero; + private Vector2 m_StackScrollPosition = Vector2.zero; + private int m_InfoCount = 0; + private int m_WarningCount = 0; + private int m_ErrorCount = 0; + private int m_FatalCount = 0; + private LogNode m_SelectedNode = null; + private bool m_LastLockScroll = true; + private bool m_LastInfoFilter = true; + private bool m_LastWarningFilter = true; + private bool m_LastErrorFilter = true; + private bool m_LastFatalFilter = true; + + [SerializeField] + private bool m_LockScroll = true; + + [SerializeField] + private int m_MaxLine = 100; + + [SerializeField] + private bool m_InfoFilter = true; + + [SerializeField] + private bool m_WarningFilter = true; + + [SerializeField] + private bool m_ErrorFilter = true; + + [SerializeField] + private bool m_FatalFilter = true; + + [SerializeField] + private Color32 m_InfoColor = Color.white; + + [SerializeField] + private Color32 m_WarningColor = Color.yellow; + + [SerializeField] + private Color32 m_ErrorColor = Color.red; + + [SerializeField] + private Color32 m_FatalColor = new Color(0.7f, 0.2f, 0.2f); + + public bool LockScroll + { + get + { + return m_LockScroll; + } + set + { + m_LockScroll = value; + } + } + + public int MaxLine + { + get + { + return m_MaxLine; + } + set + { + m_MaxLine = value; + } + } + + public bool InfoFilter + { + get + { + return m_InfoFilter; + } + set + { + m_InfoFilter = value; + } + } + + public bool WarningFilter + { + get + { + return m_WarningFilter; + } + set + { + m_WarningFilter = value; + } + } + + public bool ErrorFilter + { + get + { + return m_ErrorFilter; + } + set + { + m_ErrorFilter = value; + } + } + + public bool FatalFilter + { + get + { + return m_FatalFilter; + } + set + { + m_FatalFilter = value; + } + } + + public int InfoCount + { + get + { + return m_InfoCount; + } + } + + public int WarningCount + { + get + { + return m_WarningCount; + } + } + + public int ErrorCount + { + get + { + return m_ErrorCount; + } + } + + public int FatalCount + { + get + { + return m_FatalCount; + } + } + + public Color32 InfoColor + { + get + { + return m_InfoColor; + } + set + { + m_InfoColor = value; + } + } + + public Color32 WarningColor + { + get + { + return m_WarningColor; + } + set + { + m_WarningColor = value; + } + } + + public Color32 ErrorColor + { + get + { + return m_ErrorColor; + } + set + { + m_ErrorColor = value; + } + } + + public Color32 FatalColor + { + get + { + return m_FatalColor; + } + set + { + m_FatalColor = value; + } + } + + public void Initialize(params object[] args) + { + m_SettingComponent = GameEntry.GetComponent(); + if (m_SettingComponent == null) + { + Log.Fatal("Setting component is invalid."); + return; + } + + Application.logMessageReceived += OnLogMessageReceived; + m_LockScroll = m_LastLockScroll = m_SettingComponent.GetBool("Debugger.Console.LockScroll", true); + m_InfoFilter = m_LastInfoFilter = m_SettingComponent.GetBool("Debugger.Console.InfoFilter", true); + m_WarningFilter = m_LastWarningFilter = m_SettingComponent.GetBool("Debugger.Console.WarningFilter", true); + m_ErrorFilter = m_LastErrorFilter = m_SettingComponent.GetBool("Debugger.Console.ErrorFilter", true); + m_FatalFilter = m_LastFatalFilter = m_SettingComponent.GetBool("Debugger.Console.FatalFilter", true); + } + + public void Shutdown() + { + Application.logMessageReceived -= OnLogMessageReceived; + Clear(); + } + + public void OnEnter() + { + } + + public void OnLeave() + { + } + + public void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + if (m_LastLockScroll != m_LockScroll) + { + m_LastLockScroll = m_LockScroll; + m_SettingComponent.SetBool("Debugger.Console.LockScroll", m_LockScroll); + } + + if (m_LastInfoFilter != m_InfoFilter) + { + m_LastInfoFilter = m_InfoFilter; + m_SettingComponent.SetBool("Debugger.Console.InfoFilter", m_InfoFilter); + } + + if (m_LastWarningFilter != m_WarningFilter) + { + m_LastWarningFilter = m_WarningFilter; + m_SettingComponent.SetBool("Debugger.Console.WarningFilter", m_WarningFilter); + } + + if (m_LastErrorFilter != m_ErrorFilter) + { + m_LastErrorFilter = m_ErrorFilter; + m_SettingComponent.SetBool("Debugger.Console.ErrorFilter", m_ErrorFilter); + } + + if (m_LastFatalFilter != m_FatalFilter) + { + m_LastFatalFilter = m_FatalFilter; + m_SettingComponent.SetBool("Debugger.Console.FatalFilter", m_FatalFilter); + } + } + + public void OnDraw() + { + RefreshCount(); + + GUILayout.BeginHorizontal(); + { + if (GUILayout.Button("Clear All", GUILayout.Width(100f))) + { + Clear(); + } + m_LockScroll = GUILayout.Toggle(m_LockScroll, "Lock Scroll", GUILayout.Width(90f)); + GUILayout.FlexibleSpace(); + m_InfoFilter = GUILayout.Toggle(m_InfoFilter, Utility.Text.Format("Info ({0})", m_InfoCount), GUILayout.Width(90f)); + m_WarningFilter = GUILayout.Toggle(m_WarningFilter, Utility.Text.Format("Warning ({0})", m_WarningCount), GUILayout.Width(90f)); + m_ErrorFilter = GUILayout.Toggle(m_ErrorFilter, Utility.Text.Format("Error ({0})", m_ErrorCount), GUILayout.Width(90f)); + m_FatalFilter = GUILayout.Toggle(m_FatalFilter, Utility.Text.Format("Fatal ({0})", m_FatalCount), GUILayout.Width(90f)); + } + GUILayout.EndHorizontal(); + + GUILayout.BeginVertical("box"); + { + if (m_LockScroll) + { + m_LogScrollPosition.y = float.MaxValue; + } + + m_LogScrollPosition = GUILayout.BeginScrollView(m_LogScrollPosition); + { + bool selected = false; + foreach (LogNode logNode in m_LogNodes) + { + switch (logNode.LogType) + { + case LogType.Log: + if (!m_InfoFilter) + { + continue; + } + break; + + case LogType.Warning: + if (!m_WarningFilter) + { + continue; + } + break; + + case LogType.Error: + if (!m_ErrorFilter) + { + continue; + } + break; + + case LogType.Exception: + if (!m_FatalFilter) + { + continue; + } + break; + } + if (GUILayout.Toggle(m_SelectedNode == logNode, GetLogString(logNode))) + { + selected = true; + if (m_SelectedNode != logNode) + { + m_SelectedNode = logNode; + m_StackScrollPosition = Vector2.zero; + } + } + } + if (!selected) + { + m_SelectedNode = null; + } + } + GUILayout.EndScrollView(); + } + GUILayout.EndVertical(); + + GUILayout.BeginVertical("box"); + { + m_StackScrollPosition = GUILayout.BeginScrollView(m_StackScrollPosition, GUILayout.Height(100f)); + { + if (m_SelectedNode != null) + { + Color32 color = GetLogStringColor(m_SelectedNode.LogType); + if (GUILayout.Button(Utility.Text.Format("{4}{6}{6}{5}", color.r, color.g, color.b, color.a, m_SelectedNode.LogMessage, m_SelectedNode.StackTrack, Environment.NewLine), "label")) + { + CopyToClipboard(Utility.Text.Format("{0}{2}{2}{1}", m_SelectedNode.LogMessage, m_SelectedNode.StackTrack, Environment.NewLine)); + } + } + } + GUILayout.EndScrollView(); + } + GUILayout.EndVertical(); + } + + private void Clear() + { + m_LogNodes.Clear(); + } + + public void RefreshCount() + { + m_InfoCount = 0; + m_WarningCount = 0; + m_ErrorCount = 0; + m_FatalCount = 0; + foreach (LogNode logNode in m_LogNodes) + { + switch (logNode.LogType) + { + case LogType.Log: + m_InfoCount++; + break; + + case LogType.Warning: + m_WarningCount++; + break; + + case LogType.Error: + m_ErrorCount++; + break; + + case LogType.Exception: + m_FatalCount++; + break; + } + } + } + + public void GetRecentLogs(List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + foreach (LogNode logNode in m_LogNodes) + { + results.Add(logNode); + } + } + + public void GetRecentLogs(List results, int count) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + if (count <= 0) + { + Log.Error("Count is invalid."); + return; + } + + int position = m_LogNodes.Count - count; + if (position < 0) + { + position = 0; + } + + int index = 0; + results.Clear(); + foreach (LogNode logNode in m_LogNodes) + { + if (index++ < position) + { + continue; + } + + results.Add(logNode); + } + } + + private void OnLogMessageReceived(string logMessage, string stackTrace, LogType logType) + { + if (logType == LogType.Assert) + { + logType = LogType.Error; + } + + m_LogNodes.Enqueue(LogNode.Create(logType, logMessage, stackTrace)); + while (m_LogNodes.Count > m_MaxLine) + { + ReferencePool.Release(m_LogNodes.Dequeue()); + } + } + + private string GetLogString(LogNode logNode) + { + Color32 color = GetLogStringColor(logNode.LogType); + return Utility.Text.Format("[{4:HH:mm:ss.fff}][{5}] {6}", color.r, color.g, color.b, color.a, logNode.LogTime.ToLocalTime(), logNode.LogFrameCount, logNode.LogMessage); + } + + internal Color32 GetLogStringColor(LogType logType) + { + Color32 color = Color.white; + switch (logType) + { + case LogType.Log: + color = m_InfoColor; + break; + + case LogType.Warning: + color = m_WarningColor; + break; + + case LogType.Error: + color = m_ErrorColor; + break; + + case LogType.Exception: + color = m_FatalColor; + break; + } + + return color; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ConsoleWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ConsoleWindow.cs.meta new file mode 100644 index 0000000..8bfcbe3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ConsoleWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a47e2730f999784eb1bbeefab72ef11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.EnvironmentInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.EnvironmentInformationWindow.cs new file mode 100644 index 0000000..ff5b6ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.EnvironmentInformationWindow.cs @@ -0,0 +1,96 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; +#if UNITY_5_5_OR_NEWER +using UnityEngine.Rendering; +#endif + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class EnvironmentInformationWindow : ScrollableDebuggerWindowBase + { + private BaseComponent m_BaseComponent = null; + private ResourceComponent m_ResourceComponent = null; + + public override void Initialize(params object[] args) + { + m_BaseComponent = GameEntry.GetComponent(); + if (m_BaseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_ResourceComponent = GameEntry.GetComponent(); + if (m_ResourceComponent == null) + { + Log.Fatal("Resource component is invalid."); + return; + } + } + + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Environment Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Product Name", Application.productName); + DrawItem("Company Name", Application.companyName); +#if UNITY_5_6_OR_NEWER + DrawItem("Game Identifier", Application.identifier); +#else + DrawItem("Game Identifier", Application.bundleIdentifier); +#endif + DrawItem("Game Framework Version", Version.GameFrameworkVersion); + DrawItem("Game Version", Utility.Text.Format("{0} ({1})", Version.GameVersion, Version.InternalGameVersion)); + DrawItem("Resource Version", m_BaseComponent.EditorResourceMode ? "Unavailable in editor resource mode" : (string.IsNullOrEmpty(m_ResourceComponent.ApplicableGameVersion) ? "Unknown" : Utility.Text.Format("{0} ({1})", m_ResourceComponent.ApplicableGameVersion, m_ResourceComponent.InternalResourceVersion))); + DrawItem("Application Version", Application.version); + DrawItem("Unity Version", Application.unityVersion); + DrawItem("Platform", Application.platform.ToString()); + DrawItem("System Language", Application.systemLanguage.ToString()); + DrawItem("Cloud Project Id", Application.cloudProjectId); +#if UNITY_5_6_OR_NEWER + DrawItem("Build Guid", Application.buildGUID); +#endif + DrawItem("Target Frame Rate", Application.targetFrameRate.ToString()); + DrawItem("Internet Reachability", Application.internetReachability.ToString()); + DrawItem("Background Loading Priority", Application.backgroundLoadingPriority.ToString()); + DrawItem("Is Playing", Application.isPlaying.ToString()); +#if UNITY_5_5_OR_NEWER + DrawItem("Splash Screen Is Finished", SplashScreen.isFinished.ToString()); +#else + DrawItem("Is Showing Splash Screen", Application.isShowingSplashScreen.ToString()); +#endif + DrawItem("Run In Background", Application.runInBackground.ToString()); +#if UNITY_5_5_OR_NEWER + DrawItem("Install Name", Application.installerName); +#endif + DrawItem("Install Mode", Application.installMode.ToString()); + DrawItem("Sandbox Type", Application.sandboxType.ToString()); + DrawItem("Is Mobile Platform", Application.isMobilePlatform.ToString()); + DrawItem("Is Console Platform", Application.isConsolePlatform.ToString()); + DrawItem("Is Editor", Application.isEditor.ToString()); + DrawItem("Is Debug Build", Debug.isDebugBuild.ToString()); +#if UNITY_5_6_OR_NEWER + DrawItem("Is Focused", Application.isFocused.ToString()); +#endif +#if UNITY_2018_2_OR_NEWER + DrawItem("Is Batch Mode", Application.isBatchMode.ToString()); +#endif +#if UNITY_5_3 + DrawItem("Stack Trace Log Type", Application.stackTraceLogType.ToString()); +#endif + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.EnvironmentInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.EnvironmentInformationWindow.cs.meta new file mode 100644 index 0000000..6fea0ee --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.EnvironmentInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c52c8dc8849c5fb429c50b45975a599b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.FpsCounter.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.FpsCounter.cs new file mode 100644 index 0000000..87d24bd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.FpsCounter.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class FpsCounter + { + private float m_UpdateInterval; + private float m_CurrentFps; + private int m_Frames; + private float m_Accumulator; + private float m_TimeLeft; + + public FpsCounter(float updateInterval) + { + if (updateInterval <= 0f) + { + Log.Error("Update interval is invalid."); + return; + } + + m_UpdateInterval = updateInterval; + Reset(); + } + + public float UpdateInterval + { + get + { + return m_UpdateInterval; + } + set + { + if (value <= 0f) + { + Log.Error("Update interval is invalid."); + return; + } + + m_UpdateInterval = value; + Reset(); + } + } + + public float CurrentFps + { + get + { + return m_CurrentFps; + } + } + + public void Update(float elapseSeconds, float realElapseSeconds) + { + m_Frames++; + m_Accumulator += realElapseSeconds; + m_TimeLeft -= realElapseSeconds; + + if (m_TimeLeft <= 0f) + { + m_CurrentFps = m_Accumulator > 0f ? m_Frames / m_Accumulator : 0f; + m_Frames = 0; + m_Accumulator = 0f; + m_TimeLeft += m_UpdateInterval; + } + } + + private void Reset() + { + m_CurrentFps = 0f; + m_Frames = 0; + m_Accumulator = 0f; + m_TimeLeft = 0f; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.FpsCounter.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.FpsCounter.cs.meta new file mode 100644 index 0000000..6c6467c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.FpsCounter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f24c805ead515d4286d3c03cd50f750 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.GraphicsInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.GraphicsInformationWindow.cs new file mode 100644 index 0000000..9f6bed8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.GraphicsInformationWindow.cs @@ -0,0 +1,170 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class GraphicsInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Graphics Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Device ID", SystemInfo.graphicsDeviceID.ToString()); + DrawItem("Device Name", SystemInfo.graphicsDeviceName); + DrawItem("Device Vendor ID", SystemInfo.graphicsDeviceVendorID.ToString()); + DrawItem("Device Vendor", SystemInfo.graphicsDeviceVendor); + DrawItem("Device Type", SystemInfo.graphicsDeviceType.ToString()); + DrawItem("Device Version", SystemInfo.graphicsDeviceVersion); + DrawItem("Memory Size", Utility.Text.Format("{0} MB", SystemInfo.graphicsMemorySize)); + DrawItem("Multi Threaded", SystemInfo.graphicsMultiThreaded.ToString()); +#if UNITY_2019_3_OR_NEWER + DrawItem("Rendering Threading Mode", SystemInfo.renderingThreadingMode.ToString()); +#endif +#if UNITY_2020_1_OR_NEWER + DrawItem("HRD Display Support Flags", SystemInfo.hdrDisplaySupportFlags.ToString()); +#endif + DrawItem("Shader Level", GetShaderLevelString(SystemInfo.graphicsShaderLevel)); + DrawItem("Global Maximum LOD", Shader.globalMaximumLOD.ToString()); +#if UNITY_5_6_OR_NEWER + DrawItem("Global Render Pipeline", Shader.globalRenderPipeline); +#endif +#if UNITY_2020_2_OR_NEWER + DrawItem("Min OpenGLES Version", Graphics.minOpenGLESVersion.ToString()); +#endif +#if UNITY_5_5_OR_NEWER + DrawItem("Active Tier", Graphics.activeTier.ToString()); +#endif +#if UNITY_2017_2_OR_NEWER + DrawItem("Active Color Gamut", Graphics.activeColorGamut.ToString()); +#endif +#if UNITY_2019_2_OR_NEWER + DrawItem("Preserve Frame Buffer Alpha", Graphics.preserveFramebufferAlpha.ToString()); +#endif + DrawItem("NPOT Support", SystemInfo.npotSupport.ToString()); + DrawItem("Max Texture Size", SystemInfo.maxTextureSize.ToString()); + DrawItem("Supported Render Target Count", SystemInfo.supportedRenderTargetCount.ToString()); +#if UNITY_2019_3_OR_NEWER + DrawItem("Supported Random Write Target Count", SystemInfo.supportedRandomWriteTargetCount.ToString()); +#endif +#if UNITY_5_4_OR_NEWER + DrawItem("Copy Texture Support", SystemInfo.copyTextureSupport.ToString()); +#endif +#if UNITY_5_5_OR_NEWER + DrawItem("Uses Reversed ZBuffer", SystemInfo.usesReversedZBuffer.ToString()); +#endif +#if UNITY_5_6_OR_NEWER + DrawItem("Max Cubemap Size", SystemInfo.maxCubemapSize.ToString()); + DrawItem("Graphics UV Starts At Top", SystemInfo.graphicsUVStartsAtTop.ToString()); +#endif +#if UNITY_2020_2_OR_NEWER + DrawItem("Constant Buffer Offset Alignment", SystemInfo.constantBufferOffsetAlignment.ToString()); +#elif UNITY_2019_1_OR_NEWER + DrawItem("Min Constant Buffer Offset Alignment", SystemInfo.minConstantBufferOffsetAlignment.ToString()); +#endif +#if UNITY_2018_3_OR_NEWER + DrawItem("Has Hidden Surface Removal On GPU", SystemInfo.hasHiddenSurfaceRemovalOnGPU.ToString()); + DrawItem("Has Dynamic Uniform Array Indexing In Fragment Shaders", SystemInfo.hasDynamicUniformArrayIndexingInFragmentShaders.ToString()); +#endif +#if UNITY_2019_2_OR_NEWER + DrawItem("Has Mip Max Level", SystemInfo.hasMipMaxLevel.ToString()); +#endif +#if UNITY_2019_3_OR_NEWER + DrawItem("Uses Load Store Actions", SystemInfo.usesLoadStoreActions.ToString()); + DrawItem("Max Compute Buffer Inputs Compute", SystemInfo.maxComputeBufferInputsCompute.ToString()); + DrawItem("Max Compute Buffer Inputs Domain", SystemInfo.maxComputeBufferInputsDomain.ToString()); + DrawItem("Max Compute Buffer Inputs Fragment", SystemInfo.maxComputeBufferInputsFragment.ToString()); + DrawItem("Max Compute Buffer Inputs Geometry", SystemInfo.maxComputeBufferInputsGeometry.ToString()); + DrawItem("Max Compute Buffer Inputs Hull", SystemInfo.maxComputeBufferInputsHull.ToString()); + DrawItem("Max Compute Buffer Inputs Vertex", SystemInfo.maxComputeBufferInputsVertex.ToString()); + DrawItem("Max Compute Work Group Size", SystemInfo.maxComputeWorkGroupSize.ToString()); + DrawItem("Max Compute Work Group Size X", SystemInfo.maxComputeWorkGroupSizeX.ToString()); + DrawItem("Max Compute Work Group Size Y", SystemInfo.maxComputeWorkGroupSizeY.ToString()); + DrawItem("Max Compute Work Group Size Z", SystemInfo.maxComputeWorkGroupSizeZ.ToString()); +#endif +#if UNITY_5_3 || UNITY_5_4 + DrawItem("Supports Stencil", SystemInfo.supportsStencil.ToString()); + DrawItem("Supports Render Textures", SystemInfo.supportsRenderTextures.ToString()); +#endif + DrawItem("Supports Sparse Textures", SystemInfo.supportsSparseTextures.ToString()); + DrawItem("Supports 3D Textures", SystemInfo.supports3DTextures.ToString()); + DrawItem("Supports Shadows", SystemInfo.supportsShadows.ToString()); + DrawItem("Supports Raw Shadow Depth Sampling", SystemInfo.supportsRawShadowDepthSampling.ToString()); +#if !UNITY_2019_1_OR_NEWER + DrawItem("Supports Render To Cubemap", SystemInfo.supportsRenderToCubemap.ToString()); + DrawItem("Supports Image Effects", SystemInfo.supportsImageEffects.ToString()); +#endif + DrawItem("Supports Compute Shader", SystemInfo.supportsComputeShaders.ToString()); + DrawItem("Supports Instancing", SystemInfo.supportsInstancing.ToString()); +#if UNITY_5_4_OR_NEWER + DrawItem("Supports 2D Array Textures", SystemInfo.supports2DArrayTextures.ToString()); + DrawItem("Supports Motion Vectors", SystemInfo.supportsMotionVectors.ToString()); +#endif +#if UNITY_5_5_OR_NEWER + DrawItem("Supports Cubemap Array Textures", SystemInfo.supportsCubemapArrayTextures.ToString()); +#endif +#if UNITY_5_6_OR_NEWER + DrawItem("Supports 3D Render Textures", SystemInfo.supports3DRenderTextures.ToString()); +#endif +#if UNITY_2017_2_OR_NEWER && !UNITY_2017_2_0 || UNITY_2017_1_4 + DrawItem("Supports Texture Wrap Mirror Once", SystemInfo.supportsTextureWrapMirrorOnce.ToString()); +#endif +#if UNITY_2019_1_OR_NEWER + DrawItem("Supports Graphics Fence", SystemInfo.supportsGraphicsFence.ToString()); +#elif UNITY_2017_3_OR_NEWER + DrawItem("Supports GPU Fence", SystemInfo.supportsGPUFence.ToString()); +#endif +#if UNITY_2017_3_OR_NEWER + DrawItem("Supports Async Compute", SystemInfo.supportsAsyncCompute.ToString()); + DrawItem("Supports Multi-sampled Textures", SystemInfo.supportsMultisampledTextures.ToString()); +#endif +#if UNITY_2018_1_OR_NEWER + DrawItem("Supports Async GPU Readback", SystemInfo.supportsAsyncGPUReadback.ToString()); + DrawItem("Supports 32bits Index Buffer", SystemInfo.supports32bitsIndexBuffer.ToString()); + DrawItem("Supports Hardware Quad Topology", SystemInfo.supportsHardwareQuadTopology.ToString()); +#endif +#if UNITY_2018_2_OR_NEWER + DrawItem("Supports Mip Streaming", SystemInfo.supportsMipStreaming.ToString()); + DrawItem("Supports Multi-sample Auto Resolve", SystemInfo.supportsMultisampleAutoResolve.ToString()); +#endif +#if UNITY_2018_3_OR_NEWER + DrawItem("Supports Separated Render Targets Blend", SystemInfo.supportsSeparatedRenderTargetsBlend.ToString()); +#endif +#if UNITY_2019_1_OR_NEWER + DrawItem("Supports Set Constant Buffer", SystemInfo.supportsSetConstantBuffer.ToString()); +#endif +#if UNITY_2019_3_OR_NEWER + DrawItem("Supports Geometry Shaders", SystemInfo.supportsGeometryShaders.ToString()); + DrawItem("Supports Ray Tracing", SystemInfo.supportsRayTracing.ToString()); + DrawItem("Supports Tessellation Shaders", SystemInfo.supportsTessellationShaders.ToString()); +#endif +#if UNITY_2020_1_OR_NEWER + DrawItem("Supports Compressed 3D Textures", SystemInfo.supportsCompressed3DTextures.ToString()); + DrawItem("Supports Conservative Raster", SystemInfo.supportsConservativeRaster.ToString()); + DrawItem("Supports GPU Recorder", SystemInfo.supportsGpuRecorder.ToString()); +#endif +#if UNITY_2020_2_OR_NEWER + DrawItem("Supports Multi-sampled 2D Array Textures", SystemInfo.supportsMultisampled2DArrayTextures.ToString()); + DrawItem("Supports Multiview", SystemInfo.supportsMultiview.ToString()); + DrawItem("Supports Render Target Array Index From Vertex Shader", SystemInfo.supportsRenderTargetArrayIndexFromVertexShader.ToString()); +#endif + } + GUILayout.EndVertical(); + } + + private string GetShaderLevelString(int shaderLevel) + { + return Utility.Text.Format("Shader Model {0}.{1}", shaderLevel / 10, shaderLevel % 10); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.GraphicsInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.GraphicsInformationWindow.cs.meta new file mode 100644 index 0000000..ffd1618 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.GraphicsInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1342573add002c41b3bb1a8abb8ef3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputAccelerationInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputAccelerationInformationWindow.cs new file mode 100644 index 0000000..1bd087f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputAccelerationInformationWindow.cs @@ -0,0 +1,46 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class InputAccelerationInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Input Acceleration Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Acceleration", Input.acceleration.ToString()); + DrawItem("Acceleration Event Count", Input.accelerationEventCount.ToString()); + DrawItem("Acceleration Events", GetAccelerationEventsString(Input.accelerationEvents)); + } + GUILayout.EndVertical(); + } + + private string GetAccelerationEventString(AccelerationEvent accelerationEvent) + { + return Utility.Text.Format("{0}, {1}", accelerationEvent.acceleration, accelerationEvent.deltaTime); + } + + private string GetAccelerationEventsString(AccelerationEvent[] accelerationEvents) + { + string[] accelerationEventStrings = new string[accelerationEvents.Length]; + for (int i = 0; i < accelerationEvents.Length; i++) + { + accelerationEventStrings[i] = GetAccelerationEventString(accelerationEvents[i]); + } + + return string.Join("; ", accelerationEventStrings); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputAccelerationInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputAccelerationInformationWindow.cs.meta new file mode 100644 index 0000000..e74c151 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputAccelerationInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99bd178c0d097a24d9e04fe1522bca60 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputCompassInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputCompassInformationWindow.cs new file mode 100644 index 0000000..9b3d4de --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputCompassInformationWindow.cs @@ -0,0 +1,48 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class InputCompassInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Input Compass Information"); + GUILayout.BeginVertical("box"); + { + GUILayout.BeginHorizontal(); + { + if (GUILayout.Button("Enable", GUILayout.Height(30f))) + { + Input.compass.enabled = true; + } + if (GUILayout.Button("Disable", GUILayout.Height(30f))) + { + Input.compass.enabled = false; + } + } + GUILayout.EndHorizontal(); + + DrawItem("Enabled", Input.compass.enabled.ToString()); + if (Input.compass.enabled) + { + DrawItem("Heading Accuracy", Input.compass.headingAccuracy.ToString()); + DrawItem("Magnetic Heading", Input.compass.magneticHeading.ToString()); + DrawItem("Raw Vector", Input.compass.rawVector.ToString()); + DrawItem("Timestamp", Input.compass.timestamp.ToString()); + DrawItem("True Heading", Input.compass.trueHeading.ToString()); + } + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputCompassInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputCompassInformationWindow.cs.meta new file mode 100644 index 0000000..81d4090 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputCompassInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a8e33bb9948f7f54d988d80a6ae6a24a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputGyroscopeInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputGyroscopeInformationWindow.cs new file mode 100644 index 0000000..4c0de69 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputGyroscopeInformationWindow.cs @@ -0,0 +1,49 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class InputGyroscopeInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Input Gyroscope Information"); + GUILayout.BeginVertical("box"); + { + GUILayout.BeginHorizontal(); + { + if (GUILayout.Button("Enable", GUILayout.Height(30f))) + { + Input.gyro.enabled = true; + } + if (GUILayout.Button("Disable", GUILayout.Height(30f))) + { + Input.gyro.enabled = false; + } + } + GUILayout.EndHorizontal(); + + DrawItem("Enabled", Input.gyro.enabled.ToString()); + if (Input.gyro.enabled) + { + DrawItem("Update Interval", Input.gyro.updateInterval.ToString()); + DrawItem("Attitude", Input.gyro.attitude.eulerAngles.ToString()); + DrawItem("Gravity", Input.gyro.gravity.ToString()); + DrawItem("Rotation Rate", Input.gyro.rotationRate.ToString()); + DrawItem("Rotation Rate Unbiased", Input.gyro.rotationRateUnbiased.ToString()); + DrawItem("User Acceleration", Input.gyro.userAcceleration.ToString()); + } + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputGyroscopeInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputGyroscopeInformationWindow.cs.meta new file mode 100644 index 0000000..613ca98 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputGyroscopeInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 709450f452a296b44b4aa939cf37f37c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputLocationInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputLocationInformationWindow.cs new file mode 100644 index 0000000..a001784 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputLocationInformationWindow.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class InputLocationInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Input Location Information"); + GUILayout.BeginVertical("box"); + { + GUILayout.BeginHorizontal(); + { + if (GUILayout.Button("Enable", GUILayout.Height(30f))) + { + Input.location.Start(); + } + if (GUILayout.Button("Disable", GUILayout.Height(30f))) + { + Input.location.Stop(); + } + } + GUILayout.EndHorizontal(); + + DrawItem("Is Enabled By User", Input.location.isEnabledByUser.ToString()); + DrawItem("Status", Input.location.status.ToString()); + if (Input.location.status == LocationServiceStatus.Running) + { + DrawItem("Horizontal Accuracy", Input.location.lastData.horizontalAccuracy.ToString()); + DrawItem("Vertical Accuracy", Input.location.lastData.verticalAccuracy.ToString()); + DrawItem("Longitude", Input.location.lastData.longitude.ToString()); + DrawItem("Latitude", Input.location.lastData.latitude.ToString()); + DrawItem("Altitude", Input.location.lastData.altitude.ToString()); + DrawItem("Timestamp", Input.location.lastData.timestamp.ToString()); + } + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputLocationInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputLocationInformationWindow.cs.meta new file mode 100644 index 0000000..85e0c9f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputLocationInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 74c5698b7ee786442b28b64003f564fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputSummaryInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputSummaryInformationWindow.cs new file mode 100644 index 0000000..4ab1e5f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputSummaryInformationWindow.cs @@ -0,0 +1,39 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class InputSummaryInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Input Summary Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Back Button Leaves App", Input.backButtonLeavesApp.ToString()); + DrawItem("Device Orientation", Input.deviceOrientation.ToString()); + DrawItem("Mouse Present", Input.mousePresent.ToString()); + DrawItem("Mouse Position", Input.mousePosition.ToString()); + DrawItem("Mouse Scroll Delta", Input.mouseScrollDelta.ToString()); + DrawItem("Any Key", Input.anyKey.ToString()); + DrawItem("Any Key Down", Input.anyKeyDown.ToString()); + DrawItem("Input String", Input.inputString); + DrawItem("IME Is Selected", Input.imeIsSelected.ToString()); + DrawItem("IME Composition Mode", Input.imeCompositionMode.ToString()); + DrawItem("Compensate Sensors", Input.compensateSensors.ToString()); + DrawItem("Composition Cursor Position", Input.compositionCursorPos.ToString()); + DrawItem("Composition String", Input.compositionString); + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputSummaryInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputSummaryInformationWindow.cs.meta new file mode 100644 index 0000000..10a2fc3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputSummaryInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2756ce9647dc6a49a66c75437edef8b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputTouchInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputTouchInformationWindow.cs new file mode 100644 index 0000000..8f1449c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputTouchInformationWindow.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class InputTouchInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Input Touch Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Touch Supported", Input.touchSupported.ToString()); + DrawItem("Touch Pressure Supported", Input.touchPressureSupported.ToString()); + DrawItem("Stylus Touch Supported", Input.stylusTouchSupported.ToString()); + DrawItem("Simulate Mouse With Touches", Input.simulateMouseWithTouches.ToString()); + DrawItem("Multi Touch Enabled", Input.multiTouchEnabled.ToString()); + DrawItem("Touch Count", Input.touchCount.ToString()); + DrawItem("Touches", GetTouchesString(Input.touches)); + } + GUILayout.EndVertical(); + } + + private string GetTouchString(Touch touch) + { + return Utility.Text.Format("{0}, {1}, {2}, {3}, {4}", touch.position, touch.deltaPosition, touch.rawPosition, touch.pressure, touch.phase); + } + + private string GetTouchesString(Touch[] touches) + { + string[] touchStrings = new string[touches.Length]; + for (int i = 0; i < touches.Length; i++) + { + touchStrings[i] = GetTouchString(touches[i]); + } + + return string.Join("; ", touchStrings); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputTouchInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputTouchInformationWindow.cs.meta new file mode 100644 index 0000000..413d7ac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.InputTouchInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a76aa41d893e994f9630028d5e3001d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.LogNode.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.LogNode.cs new file mode 100644 index 0000000..b0e8d44 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.LogNode.cs @@ -0,0 +1,125 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + /// + /// 日志记录结点。 + /// + public sealed class LogNode : IReference + { + private DateTime m_LogTime; + private int m_LogFrameCount; + private LogType m_LogType; + private string m_LogMessage; + private string m_StackTrack; + + /// + /// 初始化日志记录结点的新实例。 + /// + public LogNode() + { + m_LogTime = default(DateTime); + m_LogFrameCount = 0; + m_LogType = LogType.Error; + m_LogMessage = null; + m_StackTrack = null; + } + + /// + /// 获取日志时间。 + /// + public DateTime LogTime + { + get + { + return m_LogTime; + } + } + + /// + /// 获取日志帧计数。 + /// + public int LogFrameCount + { + get + { + return m_LogFrameCount; + } + } + + /// + /// 获取日志类型。 + /// + public LogType LogType + { + get + { + return m_LogType; + } + } + + /// + /// 获取日志内容。 + /// + public string LogMessage + { + get + { + return m_LogMessage; + } + } + + /// + /// 获取日志堆栈信息。 + /// + public string StackTrack + { + get + { + return m_StackTrack; + } + } + + /// + /// 创建日志记录结点。 + /// + /// 日志类型。 + /// 日志内容。 + /// 日志堆栈信息。 + /// 创建的日志记录结点。 + public static LogNode Create(LogType logType, string logMessage, string stackTrack) + { + LogNode logNode = ReferencePool.Acquire(); + logNode.m_LogTime = DateTime.UtcNow; + logNode.m_LogFrameCount = Time.frameCount; + logNode.m_LogType = logType; + logNode.m_LogMessage = logMessage; + logNode.m_StackTrack = stackTrack; + return logNode; + } + + /// + /// 清理日志记录结点。 + /// + public void Clear() + { + m_LogTime = default(DateTime); + m_LogFrameCount = 0; + m_LogType = LogType.Error; + m_LogMessage = null; + m_StackTrack = null; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.LogNode.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.LogNode.cs.meta new file mode 100644 index 0000000..a9cd9bb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.LogNode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 168b4dfdd72224e4bbc5fb606eec23dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.NetworkInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.NetworkInformationWindow.cs new file mode 100644 index 0000000..565a63e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.NetworkInformationWindow.cs @@ -0,0 +1,70 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Network; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class NetworkInformationWindow : ScrollableDebuggerWindowBase + { + private NetworkComponent m_NetworkComponent = null; + + public override void Initialize(params object[] args) + { + m_NetworkComponent = GameEntry.GetComponent(); + if (m_NetworkComponent == null) + { + Log.Fatal("Network component is invalid."); + return; + } + } + + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Network Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Network Channel Count", m_NetworkComponent.NetworkChannelCount.ToString()); + } + GUILayout.EndVertical(); + INetworkChannel[] networkChannels = m_NetworkComponent.GetAllNetworkChannels(); + for (int i = 0; i < networkChannels.Length; i++) + { + DrawNetworkChannel(networkChannels[i]); + } + } + + private void DrawNetworkChannel(INetworkChannel networkChannel) + { + GUILayout.Label(Utility.Text.Format("Network Channel: {0} ({1})", networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected")); + GUILayout.BeginVertical("box"); + { + DrawItem("Service Type", networkChannel.ServiceType.ToString()); + DrawItem("Address Family", networkChannel.AddressFamily.ToString()); + DrawItem("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable"); + DrawItem("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable"); + DrawItem("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount, networkChannel.SentPacketCount)); + DrawItem("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount, networkChannel.ReceivedPacketCount)); + DrawItem("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString()); + DrawItem("Heart Beat", Utility.Text.Format("{0:F2} / {1:F2}", networkChannel.HeartBeatElapseSeconds, networkChannel.HeartBeatInterval)); + if (networkChannel.Connected) + { + if (GUILayout.Button("Disconnect", GUILayout.Height(30f))) + { + networkChannel.Close(); + } + } + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.NetworkInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.NetworkInformationWindow.cs.meta new file mode 100644 index 0000000..c62b961 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.NetworkInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51d087cb976f4944487629d900a5c057 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ObjectPoolInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ObjectPoolInformationWindow.cs new file mode 100644 index 0000000..4af307e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ObjectPoolInformationWindow.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.ObjectPool; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class ObjectPoolInformationWindow : ScrollableDebuggerWindowBase + { + private ObjectPoolComponent m_ObjectPoolComponent = null; + + public override void Initialize(params object[] args) + { + m_ObjectPoolComponent = GameEntry.GetComponent(); + if (m_ObjectPoolComponent == null) + { + Log.Fatal("Object pool component is invalid."); + return; + } + } + + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Object Pool Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Object Pool Count", m_ObjectPoolComponent.Count.ToString()); + } + GUILayout.EndVertical(); + ObjectPoolBase[] objectPools = m_ObjectPoolComponent.GetAllObjectPools(true); + for (int i = 0; i < objectPools.Length; i++) + { + DrawObjectPool(objectPools[i]); + } + } + + private void DrawObjectPool(ObjectPoolBase objectPool) + { + GUILayout.Label(Utility.Text.Format("Object Pool: {0}", objectPool.FullName)); + GUILayout.BeginVertical("box"); + { + DrawItem("Name", objectPool.Name); + DrawItem("Type", objectPool.ObjectType.FullName); + DrawItem("Auto Release Interval", objectPool.AutoReleaseInterval.ToString()); + DrawItem("Capacity", objectPool.Capacity.ToString()); + DrawItem("Used Count", objectPool.Count.ToString()); + DrawItem("Can Release Count", objectPool.CanReleaseCount.ToString()); + DrawItem("Expire Time", objectPool.ExpireTime.ToString()); + DrawItem("Priority", objectPool.Priority.ToString()); + ObjectInfo[] objectInfos = objectPool.GetAllObjectInfos(); + GUILayout.BeginHorizontal(); + { + GUILayout.Label("Name"); + GUILayout.Label("Locked", GUILayout.Width(60f)); + GUILayout.Label(objectPool.AllowMultiSpawn ? "Count" : "In Use", GUILayout.Width(60f)); + GUILayout.Label("Flag", GUILayout.Width(60f)); + GUILayout.Label("Priority", GUILayout.Width(60f)); + GUILayout.Label("Last Use Time", GUILayout.Width(120f)); + } + GUILayout.EndHorizontal(); + + if (objectInfos.Length > 0) + { + for (int i = 0; i < objectInfos.Length; i++) + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label(string.IsNullOrEmpty(objectInfos[i].Name) ? "" : objectInfos[i].Name); + GUILayout.Label(objectInfos[i].Locked.ToString(), GUILayout.Width(60f)); + GUILayout.Label(objectPool.AllowMultiSpawn ? objectInfos[i].SpawnCount.ToString() : objectInfos[i].IsInUse.ToString(), GUILayout.Width(60f)); + GUILayout.Label(objectInfos[i].CustomCanReleaseFlag.ToString(), GUILayout.Width(60f)); + GUILayout.Label(objectInfos[i].Priority.ToString(), GUILayout.Width(60f)); + GUILayout.Label(objectInfos[i].LastUseTime.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), GUILayout.Width(120f)); + } + GUILayout.EndHorizontal(); + } + } + else + { + GUILayout.Label("Object Pool is Empty ..."); + } + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ObjectPoolInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ObjectPoolInformationWindow.cs.meta new file mode 100644 index 0000000..03ba5f0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ObjectPoolInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5898a6ad35652924590c863ef4bc6341 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.OperationsWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.OperationsWindow.cs new file mode 100644 index 0000000..1adb7bb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.OperationsWindow.cs @@ -0,0 +1,66 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class OperationsWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Operations"); + GUILayout.BeginVertical("box"); + { + ObjectPoolComponent objectPoolComponent = GameEntry.GetComponent(); + if (objectPoolComponent != null) + { + if (GUILayout.Button("Object Pool Release", GUILayout.Height(30f))) + { + objectPoolComponent.Release(); + } + + if (GUILayout.Button("Object Pool Release All Unused", GUILayout.Height(30f))) + { + objectPoolComponent.ReleaseAllUnused(); + } + } + + ResourceComponent resourceCompoent = GameEntry.GetComponent(); + if (resourceCompoent != null) + { + if (GUILayout.Button("Unload Unused Assets", GUILayout.Height(30f))) + { + resourceCompoent.ForceUnloadUnusedAssets(false); + } + + if (GUILayout.Button("Unload Unused Assets and Garbage Collect", GUILayout.Height(30f))) + { + resourceCompoent.ForceUnloadUnusedAssets(true); + } + } + + if (GUILayout.Button("Shutdown Game Framework (None)", GUILayout.Height(30f))) + { + GameEntry.Shutdown(ShutdownType.None); + } + if (GUILayout.Button("Shutdown Game Framework (Restart)", GUILayout.Height(30f))) + { + GameEntry.Shutdown(ShutdownType.Restart); + } + if (GUILayout.Button("Shutdown Game Framework (Quit)", GUILayout.Height(30f))) + { + GameEntry.Shutdown(ShutdownType.Quit); + } + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.OperationsWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.OperationsWindow.cs.meta new file mode 100644 index 0000000..ac4e910 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.OperationsWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a695dd87b92d7374fbe3790f5a25e9d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.PathInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.PathInformationWindow.cs new file mode 100644 index 0000000..8bb0258 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.PathInformationWindow.cs @@ -0,0 +1,36 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class PathInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Path Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Current Directory", Utility.Path.GetRegularPath(Environment.CurrentDirectory)); + DrawItem("Data Path", Utility.Path.GetRegularPath(Application.dataPath)); + DrawItem("Persistent Data Path", Utility.Path.GetRegularPath(Application.persistentDataPath)); + DrawItem("Streaming Assets Path", Utility.Path.GetRegularPath(Application.streamingAssetsPath)); + DrawItem("Temporary Cache Path", Utility.Path.GetRegularPath(Application.temporaryCachePath)); +#if UNITY_2018_3_OR_NEWER + DrawItem("Console Log Path", Utility.Path.GetRegularPath(Application.consoleLogPath)); +#endif + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.PathInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.PathInformationWindow.cs.meta new file mode 100644 index 0000000..1597ff4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.PathInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e86b5be349fea7b46bf4c9cff62cf940 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ProfilerInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ProfilerInformationWindow.cs new file mode 100644 index 0000000..b14d3b7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ProfilerInformationWindow.cs @@ -0,0 +1,67 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; +#if UNITY_5_5_OR_NEWER +using UnityEngine.Profiling; +#endif + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class ProfilerInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Profiler Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Supported", Profiler.supported.ToString()); + DrawItem("Enabled", Profiler.enabled.ToString()); + DrawItem("Enable Binary Log", Profiler.enableBinaryLog ? Utility.Text.Format("True, {0}", Profiler.logFile) : "False"); +#if UNITY_2019_3_OR_NEWER + DrawItem("Enable Allocation Callstacks", Profiler.enableAllocationCallstacks.ToString()); +#endif +#if UNITY_2018_3_OR_NEWER + DrawItem("Area Count", Profiler.areaCount.ToString()); +#endif +#if UNITY_5_3 || UNITY_5_4 + DrawItem("Max Samples Number Per Frame", Profiler.maxNumberOfSamplesPerFrame.ToString()); +#endif +#if UNITY_2018_3_OR_NEWER + DrawItem("Max Used Memory", GetByteLengthString(Profiler.maxUsedMemory)); +#endif +#if UNITY_5_6_OR_NEWER + DrawItem("Mono Used Size", GetByteLengthString(Profiler.GetMonoUsedSizeLong())); + DrawItem("Mono Heap Size", GetByteLengthString(Profiler.GetMonoHeapSizeLong())); + DrawItem("Used Heap Size", GetByteLengthString(Profiler.usedHeapSizeLong)); + DrawItem("Total Allocated Memory", GetByteLengthString(Profiler.GetTotalAllocatedMemoryLong())); + DrawItem("Total Reserved Memory", GetByteLengthString(Profiler.GetTotalReservedMemoryLong())); + DrawItem("Total Unused Reserved Memory", GetByteLengthString(Profiler.GetTotalUnusedReservedMemoryLong())); +#else + DrawItem("Mono Used Size", GetByteLengthString(Profiler.GetMonoUsedSize())); + DrawItem("Mono Heap Size", GetByteLengthString(Profiler.GetMonoHeapSize())); + DrawItem("Used Heap Size", GetByteLengthString(Profiler.usedHeapSize)); + DrawItem("Total Allocated Memory", GetByteLengthString(Profiler.GetTotalAllocatedMemory())); + DrawItem("Total Reserved Memory", GetByteLengthString(Profiler.GetTotalReservedMemory())); + DrawItem("Total Unused Reserved Memory", GetByteLengthString(Profiler.GetTotalUnusedReservedMemory())); +#endif +#if UNITY_2018_1_OR_NEWER + DrawItem("Allocated Memory For Graphics Driver", GetByteLengthString(Profiler.GetAllocatedMemoryForGraphicsDriver())); +#endif +#if UNITY_5_5_OR_NEWER + DrawItem("Temp Allocator Size", GetByteLengthString(Profiler.GetTempAllocatorSize())); +#endif + DrawItem("Marshal Cached HGlobal Size", GetByteLengthString(Utility.Marshal.CachedHGlobalSize)); + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ProfilerInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ProfilerInformationWindow.cs.meta new file mode 100644 index 0000000..0e72fe2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ProfilerInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73fd64cd790a9564d9e49d13ed0742c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.QualityInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.QualityInformationWindow.cs new file mode 100644 index 0000000..e672251 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.QualityInformationWindow.cs @@ -0,0 +1,110 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class QualityInformationWindow : ScrollableDebuggerWindowBase + { + private bool m_ApplyExpensiveChanges = false; + + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Quality Level"); + GUILayout.BeginVertical("box"); + { + int currentQualityLevel = QualitySettings.GetQualityLevel(); + + DrawItem("Current Quality Level", QualitySettings.names[currentQualityLevel]); + m_ApplyExpensiveChanges = GUILayout.Toggle(m_ApplyExpensiveChanges, "Apply expensive changes on quality level change."); + + int newQualityLevel = GUILayout.SelectionGrid(currentQualityLevel, QualitySettings.names, 3, "toggle"); + if (newQualityLevel != currentQualityLevel) + { + QualitySettings.SetQualityLevel(newQualityLevel, m_ApplyExpensiveChanges); + } + } + GUILayout.EndVertical(); + + GUILayout.Label("Rendering Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Active Color Space", QualitySettings.activeColorSpace.ToString()); + DrawItem("Desired Color Space", QualitySettings.desiredColorSpace.ToString()); + DrawItem("Max Queued Frames", QualitySettings.maxQueuedFrames.ToString()); + DrawItem("Pixel Light Count", QualitySettings.pixelLightCount.ToString()); + DrawItem("Master Texture Limit", QualitySettings.globalTextureMipmapLimit.ToString()); + DrawItem("Anisotropic Filtering", QualitySettings.anisotropicFiltering.ToString()); + DrawItem("Anti Aliasing", QualitySettings.antiAliasing.ToString()); +#if UNITY_5_5_OR_NEWER + DrawItem("Soft Particles", QualitySettings.softParticles.ToString()); +#endif + DrawItem("Soft Vegetation", QualitySettings.softVegetation.ToString()); + DrawItem("Realtime Reflection Probes", QualitySettings.realtimeReflectionProbes.ToString()); + DrawItem("Billboards Face Camera Position", QualitySettings.billboardsFaceCameraPosition.ToString()); +#if UNITY_2017_1_OR_NEWER + DrawItem("Resolution Scaling Fixed DPI Factor", QualitySettings.resolutionScalingFixedDPIFactor.ToString()); +#endif +#if UNITY_2018_2_OR_NEWER + DrawItem("Texture Streaming Enabled", QualitySettings.streamingMipmapsActive.ToString()); + DrawItem("Texture Streaming Add All Cameras", QualitySettings.streamingMipmapsAddAllCameras.ToString()); + DrawItem("Texture Streaming Memory Budget", QualitySettings.streamingMipmapsMemoryBudget.ToString()); + DrawItem("Texture Streaming Renderers Per Frame", QualitySettings.streamingMipmapsRenderersPerFrame.ToString()); + DrawItem("Texture Streaming Max Level Reduction", QualitySettings.streamingMipmapsMaxLevelReduction.ToString()); + DrawItem("Texture Streaming Max File IO Requests", QualitySettings.streamingMipmapsMaxFileIORequests.ToString()); +#endif + } + GUILayout.EndVertical(); + + GUILayout.Label("Shadows Information"); + GUILayout.BeginVertical("box"); + { +#if UNITY_2017_1_OR_NEWER + DrawItem("Shadowmask Mode", QualitySettings.shadowmaskMode.ToString()); +#endif +#if UNITY_5_5_OR_NEWER + DrawItem("Shadow Quality", QualitySettings.shadows.ToString()); +#endif +#if UNITY_5_4_OR_NEWER + DrawItem("Shadow Resolution", QualitySettings.shadowResolution.ToString()); +#endif + DrawItem("Shadow Projection", QualitySettings.shadowProjection.ToString()); + DrawItem("Shadow Distance", QualitySettings.shadowDistance.ToString()); + DrawItem("Shadow Near Plane Offset", QualitySettings.shadowNearPlaneOffset.ToString()); + DrawItem("Shadow Cascades", QualitySettings.shadowCascades.ToString()); + DrawItem("Shadow Cascade 2 Split", QualitySettings.shadowCascade2Split.ToString()); + DrawItem("Shadow Cascade 4 Split", QualitySettings.shadowCascade4Split.ToString()); + } + GUILayout.EndVertical(); + + GUILayout.Label("Other Information"); + GUILayout.BeginVertical("box"); + { +#if UNITY_2019_1_OR_NEWER + DrawItem("Skin Weights", QualitySettings.skinWeights.ToString()); +#else + DrawItem("Blend Weights", QualitySettings.blendWeights.ToString()); +#endif + DrawItem("VSync Count", QualitySettings.vSyncCount.ToString()); + DrawItem("LOD Bias", QualitySettings.lodBias.ToString()); + DrawItem("Maximum LOD Level", QualitySettings.maximumLODLevel.ToString()); + DrawItem("Particle Raycast Budget", QualitySettings.particleRaycastBudget.ToString()); + DrawItem("Async Upload Time Slice", Utility.Text.Format("{0} ms", QualitySettings.asyncUploadTimeSlice)); + DrawItem("Async Upload Buffer Size", Utility.Text.Format("{0} MB", QualitySettings.asyncUploadBufferSize)); +#if UNITY_2018_3_OR_NEWER + DrawItem("Async Upload Persistent Buffer", QualitySettings.asyncUploadPersistentBuffer.ToString()); +#endif + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.QualityInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.QualityInformationWindow.cs.meta new file mode 100644 index 0000000..64b22d8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.QualityInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc21c02fdf159d840a5254513a44c065 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ReferencePoolInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ReferencePoolInformationWindow.cs new file mode 100644 index 0000000..be83f29 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ReferencePoolInformationWindow.cs @@ -0,0 +1,114 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class ReferencePoolInformationWindow : ScrollableDebuggerWindowBase + { + private readonly Dictionary> m_ReferencePoolInfos = new Dictionary>(StringComparer.Ordinal); + private readonly Comparison m_NormalClassNameComparer = NormalClassNameComparer; + private readonly Comparison m_FullClassNameComparer = FullClassNameComparer; + private bool m_ShowFullClassName = false; + + public override void Initialize(params object[] args) + { + } + + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Reference Pool Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Enable Strict Check", ReferencePool.EnableStrictCheck.ToString()); + DrawItem("Reference Pool Count", ReferencePool.Count.ToString()); + } + GUILayout.EndVertical(); + + m_ShowFullClassName = GUILayout.Toggle(m_ShowFullClassName, "Show Full Class Name"); + m_ReferencePoolInfos.Clear(); + ReferencePoolInfo[] referencePoolInfos = ReferencePool.GetAllReferencePoolInfos(); + foreach (ReferencePoolInfo referencePoolInfo in referencePoolInfos) + { + string assemblyName = referencePoolInfo.Type.Assembly.GetName().Name; + List results = null; + if (!m_ReferencePoolInfos.TryGetValue(assemblyName, out results)) + { + results = new List(); + m_ReferencePoolInfos.Add(assemblyName, results); + } + + results.Add(referencePoolInfo); + } + + foreach (KeyValuePair> assemblyReferencePoolInfo in m_ReferencePoolInfos) + { + GUILayout.Label(Utility.Text.Format("Assembly: {0}", assemblyReferencePoolInfo.Key)); + GUILayout.BeginVertical("box"); + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label(m_ShowFullClassName ? "Full Class Name" : "Class Name"); + GUILayout.Label("Unused", GUILayout.Width(60f)); + GUILayout.Label("Using", GUILayout.Width(60f)); + GUILayout.Label("Acquire", GUILayout.Width(60f)); + GUILayout.Label("Release", GUILayout.Width(60f)); + GUILayout.Label("Add", GUILayout.Width(60f)); + GUILayout.Label("Remove", GUILayout.Width(60f)); + } + GUILayout.EndHorizontal(); + + if (assemblyReferencePoolInfo.Value.Count > 0) + { + assemblyReferencePoolInfo.Value.Sort(m_ShowFullClassName ? m_FullClassNameComparer : m_NormalClassNameComparer); + foreach (ReferencePoolInfo referencePoolInfo in assemblyReferencePoolInfo.Value) + { + DrawReferencePoolInfo(referencePoolInfo); + } + } + else + { + GUILayout.Label("Reference Pool is Empty ..."); + } + } + GUILayout.EndVertical(); + } + } + + private void DrawReferencePoolInfo(ReferencePoolInfo referencePoolInfo) + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label(m_ShowFullClassName ? referencePoolInfo.Type.FullName : referencePoolInfo.Type.Name); + GUILayout.Label(referencePoolInfo.UnusedReferenceCount.ToString(), GUILayout.Width(60f)); + GUILayout.Label(referencePoolInfo.UsingReferenceCount.ToString(), GUILayout.Width(60f)); + GUILayout.Label(referencePoolInfo.AcquireReferenceCount.ToString(), GUILayout.Width(60f)); + GUILayout.Label(referencePoolInfo.ReleaseReferenceCount.ToString(), GUILayout.Width(60f)); + GUILayout.Label(referencePoolInfo.AddReferenceCount.ToString(), GUILayout.Width(60f)); + GUILayout.Label(referencePoolInfo.RemoveReferenceCount.ToString(), GUILayout.Width(60f)); + } + GUILayout.EndHorizontal(); + } + + private static int NormalClassNameComparer(ReferencePoolInfo a, ReferencePoolInfo b) + { + return a.Type.Name.CompareTo(b.Type.Name); + } + + private static int FullClassNameComparer(ReferencePoolInfo a, ReferencePoolInfo b) + { + return a.Type.FullName.CompareTo(b.Type.FullName); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ReferencePoolInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ReferencePoolInformationWindow.cs.meta new file mode 100644 index 0000000..9f4f2a1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ReferencePoolInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33068d0a27ec5684e994545a7995a17c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.Sample.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.Sample.cs new file mode 100644 index 0000000..12eead5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.Sample.cs @@ -0,0 +1,67 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed partial class RuntimeMemoryInformationWindow : ScrollableDebuggerWindowBase where T : UnityEngine.Object + { + private sealed class Sample + { + private readonly string m_Name; + private readonly string m_Type; + private readonly long m_Size; + private bool m_Highlight; + + public Sample(string name, string type, long size) + { + m_Name = name; + m_Type = type; + m_Size = size; + m_Highlight = false; + } + + public string Name + { + get + { + return m_Name; + } + } + + public string Type + { + get + { + return m_Type; + } + } + + public long Size + { + get + { + return m_Size; + } + } + + public bool Highlight + { + get + { + return m_Highlight; + } + set + { + m_Highlight = value; + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.Sample.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.Sample.cs.meta new file mode 100644 index 0000000..3bc4594 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.Sample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0da72213ab82f43458578c3ce477a57c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.cs new file mode 100644 index 0000000..7f85916 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.cs @@ -0,0 +1,142 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using UnityEngine; +#if UNITY_5_5_OR_NEWER +using UnityEngine.Profiling; +#endif + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed partial class RuntimeMemoryInformationWindow : ScrollableDebuggerWindowBase where T : UnityEngine.Object + { + private const int ShowSampleCount = 300; + + private readonly List m_Samples = new List(); + private readonly Comparison m_SampleComparer = SampleComparer; + private DateTime m_SampleTime = DateTime.MinValue; + private long m_SampleSize = 0L; + private long m_DuplicateSampleSize = 0L; + private int m_DuplicateSimpleCount = 0; + + protected override void OnDrawScrollableWindow() + { + string typeName = typeof(T).Name; + GUILayout.Label(Utility.Text.Format("{0} Runtime Memory Information", typeName)); + GUILayout.BeginVertical("box"); + { + if (GUILayout.Button(Utility.Text.Format("Take Sample for {0}", typeName), GUILayout.Height(30f))) + { + TakeSample(); + } + + if (m_SampleTime <= DateTime.MinValue) + { + GUILayout.Label(Utility.Text.Format("Please take sample for {0} first.", typeName)); + } + else + { + if (m_DuplicateSimpleCount > 0) + { + GUILayout.Label(Utility.Text.Format("{0} {1}s ({2}) obtained at {3:yyyy-MM-dd HH:mm:ss}, while {4} {1}s ({5}) might be duplicated.", m_Samples.Count, typeName, GetByteLengthString(m_SampleSize), m_SampleTime.ToLocalTime(), m_DuplicateSimpleCount, GetByteLengthString(m_DuplicateSampleSize))); + } + else + { + GUILayout.Label(Utility.Text.Format("{0} {1}s ({2}) obtained at {3:yyyy-MM-dd HH:mm:ss}.", m_Samples.Count, typeName, GetByteLengthString(m_SampleSize), m_SampleTime.ToLocalTime())); + } + + if (m_Samples.Count > 0) + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label(Utility.Text.Format("{0} Name", typeName)); + GUILayout.Label("Type", GUILayout.Width(240f)); + GUILayout.Label("Size", GUILayout.Width(80f)); + } + GUILayout.EndHorizontal(); + } + + int count = 0; + for (int i = 0; i < m_Samples.Count; i++) + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label(m_Samples[i].Highlight ? Utility.Text.Format("{0}", m_Samples[i].Name) : m_Samples[i].Name); + GUILayout.Label(m_Samples[i].Highlight ? Utility.Text.Format("{0}", m_Samples[i].Type) : m_Samples[i].Type, GUILayout.Width(240f)); + GUILayout.Label(m_Samples[i].Highlight ? Utility.Text.Format("{0}", GetByteLengthString(m_Samples[i].Size)) : GetByteLengthString(m_Samples[i].Size), GUILayout.Width(80f)); + } + GUILayout.EndHorizontal(); + + count++; + if (count >= ShowSampleCount) + { + break; + } + } + } + } + GUILayout.EndVertical(); + } + + private void TakeSample() + { + m_SampleTime = DateTime.UtcNow; + m_SampleSize = 0L; + m_DuplicateSampleSize = 0L; + m_DuplicateSimpleCount = 0; + m_Samples.Clear(); + + T[] samples = Resources.FindObjectsOfTypeAll(); + for (int i = 0; i < samples.Length; i++) + { + long sampleSize = 0L; +#if UNITY_5_6_OR_NEWER + sampleSize = Profiler.GetRuntimeMemorySizeLong(samples[i]); +#else + sampleSize = Profiler.GetRuntimeMemorySize(samples[i]); +#endif + m_SampleSize += sampleSize; + m_Samples.Add(new Sample(samples[i].name, samples[i].GetType().Name, sampleSize)); + } + + m_Samples.Sort(m_SampleComparer); + + for (int i = 1; i < m_Samples.Count; i++) + { + if (m_Samples[i].Name == m_Samples[i - 1].Name && m_Samples[i].Type == m_Samples[i - 1].Type && m_Samples[i].Size == m_Samples[i - 1].Size) + { + m_Samples[i].Highlight = true; + m_DuplicateSampleSize += m_Samples[i].Size; + m_DuplicateSimpleCount++; + } + } + } + + private static int SampleComparer(Sample a, Sample b) + { + int result = b.Size.CompareTo(a.Size); + if (result != 0) + { + return result; + } + + result = a.Type.CompareTo(b.Type); + if (result != 0) + { + return result; + } + + return a.Name.CompareTo(b.Name); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.cs.meta new file mode 100644 index 0000000..a8bb068 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemoryInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21007b3290d97754ea3ab4d9f46900e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.Record.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.Record.cs new file mode 100644 index 0000000..737e22a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.Record.cs @@ -0,0 +1,61 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed partial class RuntimeMemorySummaryWindow : ScrollableDebuggerWindowBase + { + private sealed class Record + { + private readonly string m_Name; + private int m_Count; + private long m_Size; + + public Record(string name) + { + m_Name = name; + m_Count = 0; + m_Size = 0L; + } + + public string Name + { + get + { + return m_Name; + } + } + + public int Count + { + get + { + return m_Count; + } + set + { + m_Count = value; + } + } + + public long Size + { + get + { + return m_Size; + } + set + { + m_Size = value; + } + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.Record.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.Record.cs.meta new file mode 100644 index 0000000..6fc6cfb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.Record.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 468bbdd114a04de429a6bd97b202c891 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.cs new file mode 100644 index 0000000..07b58a8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.cs @@ -0,0 +1,130 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using UnityEngine; +#if UNITY_5_5_OR_NEWER +using UnityEngine.Profiling; +#endif + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed partial class RuntimeMemorySummaryWindow : ScrollableDebuggerWindowBase + { + private readonly List m_Records = new List(); + private readonly Comparison m_RecordComparer = RecordComparer; + private DateTime m_SampleTime = DateTime.MinValue; + private int m_SampleCount = 0; + private long m_SampleSize = 0L; + + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Runtime Memory Summary"); + GUILayout.BeginVertical("box"); + { + if (GUILayout.Button("Take Sample", GUILayout.Height(30f))) + { + TakeSample(); + } + + if (m_SampleTime <= DateTime.MinValue) + { + GUILayout.Label("Please take sample first."); + } + else + { + GUILayout.Label(Utility.Text.Format("{0} Objects ({1}) obtained at {2:yyyy-MM-dd HH:mm:ss}.", m_SampleCount, GetByteLengthString(m_SampleSize), m_SampleTime.ToLocalTime())); + + GUILayout.BeginHorizontal(); + { + GUILayout.Label("Type"); + GUILayout.Label("Count", GUILayout.Width(120f)); + GUILayout.Label("Size", GUILayout.Width(120f)); + } + GUILayout.EndHorizontal(); + + for (int i = 0; i < m_Records.Count; i++) + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label(m_Records[i].Name); + GUILayout.Label(m_Records[i].Count.ToString(), GUILayout.Width(120f)); + GUILayout.Label(GetByteLengthString(m_Records[i].Size), GUILayout.Width(120f)); + } + GUILayout.EndHorizontal(); + } + } + } + GUILayout.EndVertical(); + } + + private void TakeSample() + { + m_Records.Clear(); + m_SampleTime = DateTime.UtcNow; + m_SampleCount = 0; + m_SampleSize = 0L; + + UnityEngine.Object[] samples = Resources.FindObjectsOfTypeAll(); + for (int i = 0; i < samples.Length; i++) + { + long sampleSize = 0L; +#if UNITY_5_6_OR_NEWER + sampleSize = Profiler.GetRuntimeMemorySizeLong(samples[i]); +#else + sampleSize = Profiler.GetRuntimeMemorySize(samples[i]); +#endif + string name = samples[i].GetType().Name; + m_SampleCount++; + m_SampleSize += sampleSize; + + Record record = null; + foreach (Record r in m_Records) + { + if (r.Name == name) + { + record = r; + break; + } + } + + if (record == null) + { + record = new Record(name); + m_Records.Add(record); + } + + record.Count++; + record.Size += sampleSize; + } + + m_Records.Sort(m_RecordComparer); + } + + private static int RecordComparer(Record a, Record b) + { + int result = b.Size.CompareTo(a.Size); + if (result != 0) + { + return result; + } + + result = a.Count.CompareTo(b.Count); + if (result != 0) + { + return result; + } + + return a.Name.CompareTo(b.Name); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.cs.meta new file mode 100644 index 0000000..df2dac1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.RuntimeMemorySummaryWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45a9f76b48e192d44b0de0eac60975b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SceneInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SceneInformationWindow.cs new file mode 100644 index 0000000..7b0b143 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SceneInformationWindow.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class SceneInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Scene Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Scene Count", SceneManager.sceneCount.ToString()); + DrawItem("Scene Count In Build Settings", SceneManager.sceneCountInBuildSettings.ToString()); + + Scene activeScene = SceneManager.GetActiveScene(); +#if UNITY_2018_3_OR_NEWER + DrawItem("Active Scene Handle", activeScene.handle.ToString()); +#endif + DrawItem("Active Scene Name", activeScene.name); + DrawItem("Active Scene Path", activeScene.path); + DrawItem("Active Scene Build Index", activeScene.buildIndex.ToString()); + DrawItem("Active Scene Is Dirty", activeScene.isDirty.ToString()); + DrawItem("Active Scene Is Loaded", activeScene.isLoaded.ToString()); + DrawItem("Active Scene Is Valid", activeScene.IsValid().ToString()); + DrawItem("Active Scene Root Count", activeScene.rootCount.ToString()); +#if UNITY_2019_1_OR_NEWER + DrawItem("Active Scene Is Sub Scene", activeScene.isSubScene.ToString()); +#endif + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SceneInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SceneInformationWindow.cs.meta new file mode 100644 index 0000000..9a51a2d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SceneInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c5471e8b14eef444a96f1e1cb4b6987 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScreenInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScreenInformationWindow.cs new file mode 100644 index 0000000..5f8b614 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScreenInformationWindow.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class ScreenInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Screen Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Current Resolution", GetResolutionString(Screen.currentResolution)); + DrawItem("Screen Width", Utility.Text.Format("{0} px / {1:F2} in / {2:F2} cm", Screen.width, Utility.Converter.GetInchesFromPixels(Screen.width), Utility.Converter.GetCentimetersFromPixels(Screen.width))); + DrawItem("Screen Height", Utility.Text.Format("{0} px / {1:F2} in / {2:F2} cm", Screen.height, Utility.Converter.GetInchesFromPixels(Screen.height), Utility.Converter.GetCentimetersFromPixels(Screen.height))); + DrawItem("Screen DPI", Screen.dpi.ToString("F2")); + DrawItem("Screen Orientation", Screen.orientation.ToString()); + DrawItem("Is Full Screen", Screen.fullScreen.ToString()); +#if UNITY_2018_1_OR_NEWER + DrawItem("Full Screen Mode", Screen.fullScreenMode.ToString()); +#endif + DrawItem("Sleep Timeout", GetSleepTimeoutDescription(Screen.sleepTimeout)); +#if UNITY_2019_2_OR_NEWER + DrawItem("Brightness", Screen.brightness.ToString("F2")); +#endif + DrawItem("Cursor Visible", Cursor.visible.ToString()); + DrawItem("Cursor Lock State", Cursor.lockState.ToString()); + DrawItem("Auto Landscape Left", Screen.autorotateToLandscapeLeft.ToString()); + DrawItem("Auto Landscape Right", Screen.autorotateToLandscapeRight.ToString()); + DrawItem("Auto Portrait", Screen.autorotateToPortrait.ToString()); + DrawItem("Auto Portrait Upside Down", Screen.autorotateToPortraitUpsideDown.ToString()); +#if UNITY_2017_2_OR_NEWER && !UNITY_2017_2_0 + DrawItem("Safe Area", Screen.safeArea.ToString()); +#endif +#if UNITY_2019_2_OR_NEWER + DrawItem("Cutouts", GetCutoutsString(Screen.cutouts)); +#endif + DrawItem("Support Resolutions", GetResolutionsString(Screen.resolutions)); + } + GUILayout.EndVertical(); + } + + private string GetSleepTimeoutDescription(int sleepTimeout) + { + if (sleepTimeout == SleepTimeout.NeverSleep) + { + return "Never Sleep"; + } + + if (sleepTimeout == SleepTimeout.SystemSetting) + { + return "System Setting"; + } + + return sleepTimeout.ToString(); + } + + private string GetResolutionString(Resolution resolution) + { + return Utility.Text.Format("{0} x {1} @ {2}Hz", resolution.width, resolution.height, resolution.refreshRateRatio); + } + + private string GetCutoutsString(Rect[] cutouts) + { + string[] cutoutStrings = new string[cutouts.Length]; + for (int i = 0; i < cutouts.Length; i++) + { + cutoutStrings[i] = cutouts[i].ToString(); + } + + return string.Join("; ", cutoutStrings); + } + + private string GetResolutionsString(Resolution[] resolutions) + { + string[] resolutionStrings = new string[resolutions.Length]; + for (int i = 0; i < resolutions.Length; i++) + { + resolutionStrings[i] = GetResolutionString(resolutions[i]); + } + + return string.Join("; ", resolutionStrings); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScreenInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScreenInformationWindow.cs.meta new file mode 100644 index 0000000..d8bcd4e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScreenInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc352756f31513048a46e56ad2900db7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScrollableDebuggerWindowBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScrollableDebuggerWindowBase.cs new file mode 100644 index 0000000..dc2e122 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScrollableDebuggerWindowBase.cs @@ -0,0 +1,101 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Debugger; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private abstract class ScrollableDebuggerWindowBase : IDebuggerWindow + { + private const float TitleWidth = 240f; + private Vector2 m_ScrollPosition = Vector2.zero; + + public virtual void Initialize(params object[] args) + { + } + + public virtual void Shutdown() + { + } + + public virtual void OnEnter() + { + } + + public virtual void OnLeave() + { + } + + public virtual void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + } + + public void OnDraw() + { + m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition); + { + OnDrawScrollableWindow(); + } + GUILayout.EndScrollView(); + } + + protected abstract void OnDrawScrollableWindow(); + + protected static void DrawItem(string title, string content) + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label(title, GUILayout.Width(TitleWidth)); + if (GUILayout.Button(content, "label")) + { + CopyToClipboard(content); + } + } + GUILayout.EndHorizontal(); + } + + protected static string GetByteLengthString(long byteLength) + { + if (byteLength < 1024L) // 2 ^ 10 + { + return Utility.Text.Format("{0} Bytes", byteLength); + } + + if (byteLength < 1048576L) // 2 ^ 20 + { + return Utility.Text.Format("{0:F2} KB", byteLength / 1024f); + } + + if (byteLength < 1073741824L) // 2 ^ 30 + { + return Utility.Text.Format("{0:F2} MB", byteLength / 1048576f); + } + + if (byteLength < 1099511627776L) // 2 ^ 40 + { + return Utility.Text.Format("{0:F2} GB", byteLength / 1073741824f); + } + + if (byteLength < 1125899906842624L) // 2 ^ 50 + { + return Utility.Text.Format("{0:F2} TB", byteLength / 1099511627776f); + } + + if (byteLength < 1152921504606846976L) // 2 ^ 60 + { + return Utility.Text.Format("{0:F2} PB", byteLength / 1125899906842624f); + } + + return Utility.Text.Format("{0:F2} EB", byteLength / 1152921504606846976f); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScrollableDebuggerWindowBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScrollableDebuggerWindowBase.cs.meta new file mode 100644 index 0000000..c00e15b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.ScrollableDebuggerWindowBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1af7b258c93df0341a163adfdd378f8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SettingsWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SettingsWindow.cs new file mode 100644 index 0000000..0803054 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SettingsWindow.cs @@ -0,0 +1,219 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class SettingsWindow : ScrollableDebuggerWindowBase + { + private DebuggerComponent m_DebuggerComponent = null; + private SettingComponent m_SettingComponent = null; + private float m_LastIconX = 0f; + private float m_LastIconY = 0f; + private float m_LastWindowX = 0f; + private float m_LastWindowY = 0f; + private float m_LastWindowWidth = 0f; + private float m_LastWindowHeight = 0f; + private float m_LastWindowScale = 0f; + + public override void Initialize(params object[] args) + { + m_DebuggerComponent = GameEntry.GetComponent(); + if (m_DebuggerComponent == null) + { + Log.Fatal("Debugger component is invalid."); + return; + } + + m_SettingComponent = GameEntry.GetComponent(); + if (m_SettingComponent == null) + { + Log.Fatal("Setting component is invalid."); + return; + } + + m_LastIconX = m_SettingComponent.GetFloat("Debugger.Icon.X", DefaultIconRect.x); + m_LastIconY = m_SettingComponent.GetFloat("Debugger.Icon.Y", DefaultIconRect.y); + m_LastWindowX = m_SettingComponent.GetFloat("Debugger.Window.X", DefaultWindowRect.x); + m_LastWindowY = m_SettingComponent.GetFloat("Debugger.Window.Y", DefaultWindowRect.y); + m_LastWindowWidth = m_SettingComponent.GetFloat("Debugger.Window.Width", DefaultWindowRect.width); + m_LastWindowHeight = m_SettingComponent.GetFloat("Debugger.Window.Height", DefaultWindowRect.height); + m_DebuggerComponent.WindowScale = m_LastWindowScale = m_SettingComponent.GetFloat("Debugger.Window.Scale", DefaultWindowScale); + m_DebuggerComponent.IconRect = new Rect(m_LastIconX, m_LastIconY, DefaultIconRect.width, DefaultIconRect.height); + m_DebuggerComponent.WindowRect = new Rect(m_LastWindowX, m_LastWindowY, m_LastWindowWidth, m_LastWindowHeight); + } + + public override void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + if (m_LastIconX != m_DebuggerComponent.IconRect.x) + { + m_LastIconX = m_DebuggerComponent.IconRect.x; + m_SettingComponent.SetFloat("Debugger.Icon.X", m_DebuggerComponent.IconRect.x); + } + + if (m_LastIconY != m_DebuggerComponent.IconRect.y) + { + m_LastIconY = m_DebuggerComponent.IconRect.y; + m_SettingComponent.SetFloat("Debugger.Icon.Y", m_DebuggerComponent.IconRect.y); + } + + if (m_LastWindowX != m_DebuggerComponent.WindowRect.x) + { + m_LastWindowX = m_DebuggerComponent.WindowRect.x; + m_SettingComponent.SetFloat("Debugger.Window.X", m_DebuggerComponent.WindowRect.x); + } + + if (m_LastWindowY != m_DebuggerComponent.WindowRect.y) + { + m_LastWindowY = m_DebuggerComponent.WindowRect.y; + m_SettingComponent.SetFloat("Debugger.Window.Y", m_DebuggerComponent.WindowRect.y); + } + + if (m_LastWindowWidth != m_DebuggerComponent.WindowRect.width) + { + m_LastWindowWidth = m_DebuggerComponent.WindowRect.width; + m_SettingComponent.SetFloat("Debugger.Window.Width", m_DebuggerComponent.WindowRect.width); + } + + if (m_LastWindowHeight != m_DebuggerComponent.WindowRect.height) + { + m_LastWindowHeight = m_DebuggerComponent.WindowRect.height; + m_SettingComponent.SetFloat("Debugger.Window.Height", m_DebuggerComponent.WindowRect.height); + } + + if (m_LastWindowScale != m_DebuggerComponent.WindowScale) + { + m_LastWindowScale = m_DebuggerComponent.WindowScale; + m_SettingComponent.SetFloat("Debugger.Window.Scale", m_DebuggerComponent.WindowScale); + } + } + + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Window Settings"); + GUILayout.BeginVertical("box"); + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label("Position:", GUILayout.Width(60f)); + GUILayout.Label("Drag window caption to move position."); + } + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + { + float width = m_DebuggerComponent.WindowRect.width; + GUILayout.Label("Width:", GUILayout.Width(60f)); + if (GUILayout.RepeatButton("-", GUILayout.Width(30f))) + { + width--; + } + width = GUILayout.HorizontalSlider(width, 100f, Screen.width - 20f); + if (GUILayout.RepeatButton("+", GUILayout.Width(30f))) + { + width++; + } + width = Mathf.Clamp(width, 100f, Screen.width - 20f); + if (width != m_DebuggerComponent.WindowRect.width) + { + m_DebuggerComponent.WindowRect = new Rect(m_DebuggerComponent.WindowRect.x, m_DebuggerComponent.WindowRect.y, width, m_DebuggerComponent.WindowRect.height); + } + } + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + { + float height = m_DebuggerComponent.WindowRect.height; + GUILayout.Label("Height:", GUILayout.Width(60f)); + if (GUILayout.RepeatButton("-", GUILayout.Width(30f))) + { + height--; + } + height = GUILayout.HorizontalSlider(height, 100f, Screen.height - 20f); + if (GUILayout.RepeatButton("+", GUILayout.Width(30f))) + { + height++; + } + height = Mathf.Clamp(height, 100f, Screen.height - 20f); + if (height != m_DebuggerComponent.WindowRect.height) + { + m_DebuggerComponent.WindowRect = new Rect(m_DebuggerComponent.WindowRect.x, m_DebuggerComponent.WindowRect.y, m_DebuggerComponent.WindowRect.width, height); + } + } + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + { + float scale = m_DebuggerComponent.WindowScale; + GUILayout.Label("Scale:", GUILayout.Width(60f)); + if (GUILayout.RepeatButton("-", GUILayout.Width(30f))) + { + scale -= 0.01f; + } + scale = GUILayout.HorizontalSlider(scale, 0.5f, 4f); + if (GUILayout.RepeatButton("+", GUILayout.Width(30f))) + { + scale += 0.01f; + } + scale = Mathf.Clamp(scale, 0.5f, 4f); + if (scale != m_DebuggerComponent.WindowScale) + { + m_DebuggerComponent.WindowScale = scale; + } + } + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + { + if (GUILayout.Button("0.5x", GUILayout.Height(60f))) + { + m_DebuggerComponent.WindowScale = 0.5f; + } + if (GUILayout.Button("1.0x", GUILayout.Height(60f))) + { + m_DebuggerComponent.WindowScale = 1f; + } + if (GUILayout.Button("1.5x", GUILayout.Height(60f))) + { + m_DebuggerComponent.WindowScale = 1.5f; + } + if (GUILayout.Button("2.0x", GUILayout.Height(60f))) + { + m_DebuggerComponent.WindowScale = 2f; + } + if (GUILayout.Button("2.5x", GUILayout.Height(60f))) + { + m_DebuggerComponent.WindowScale = 2.5f; + } + if (GUILayout.Button("3.0x", GUILayout.Height(60f))) + { + m_DebuggerComponent.WindowScale = 3f; + } + if (GUILayout.Button("3.5x", GUILayout.Height(60f))) + { + m_DebuggerComponent.WindowScale = 3.5f; + } + if (GUILayout.Button("4.0x", GUILayout.Height(60f))) + { + m_DebuggerComponent.WindowScale = 4f; + } + } + GUILayout.EndHorizontal(); + + if (GUILayout.Button("Reset Layout", GUILayout.Height(30f))) + { + m_DebuggerComponent.ResetLayout(); + } + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SettingsWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SettingsWindow.cs.meta new file mode 100644 index 0000000..e73c3d9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SettingsWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4a36d102b4e1a648810a983c2101967 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SystemInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SystemInformationWindow.cs new file mode 100644 index 0000000..6ade6bd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SystemInformationWindow.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class SystemInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("System Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Device Unique ID", SystemInfo.deviceUniqueIdentifier); + DrawItem("Device Name", SystemInfo.deviceName); + DrawItem("Device Type", SystemInfo.deviceType.ToString()); + DrawItem("Device Model", SystemInfo.deviceModel); + DrawItem("Processor Type", SystemInfo.processorType); + DrawItem("Processor Count", SystemInfo.processorCount.ToString()); + DrawItem("Processor Frequency", Utility.Text.Format("{0} MHz", SystemInfo.processorFrequency)); + DrawItem("System Memory Size", Utility.Text.Format("{0} MB", SystemInfo.systemMemorySize)); +#if UNITY_5_5_OR_NEWER + DrawItem("Operating System Family", SystemInfo.operatingSystemFamily.ToString()); +#endif + DrawItem("Operating System", SystemInfo.operatingSystem); +#if UNITY_5_6_OR_NEWER + DrawItem("Battery Status", SystemInfo.batteryStatus.ToString()); + DrawItem("Battery Level", GetBatteryLevelString(SystemInfo.batteryLevel)); +#endif +#if UNITY_5_4_OR_NEWER + DrawItem("Supports Audio", SystemInfo.supportsAudio.ToString()); +#endif + DrawItem("Supports Location Service", SystemInfo.supportsLocationService.ToString()); + DrawItem("Supports Accelerometer", SystemInfo.supportsAccelerometer.ToString()); + DrawItem("Supports Gyroscope", SystemInfo.supportsGyroscope.ToString()); + DrawItem("Supports Vibration", SystemInfo.supportsVibration.ToString()); + DrawItem("Genuine", Application.genuine.ToString()); + DrawItem("Genuine Check Available", Application.genuineCheckAvailable.ToString()); + } + GUILayout.EndVertical(); + } + + private string GetBatteryLevelString(float batteryLevel) + { + if (batteryLevel < 0f) + { + return "Unavailable"; + } + + return batteryLevel.ToString("P0"); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SystemInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SystemInformationWindow.cs.meta new file mode 100644 index 0000000..b8505c5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.SystemInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 788d38477d0fde741b8939db86e6a083 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.TimeInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.TimeInformationWindow.cs new file mode 100644 index 0000000..d1a9409 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.TimeInformationWindow.cs @@ -0,0 +1,76 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class TimeInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Time Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Time Scale", Utility.Text.Format("{0} [{1}]", Time.timeScale, GetTimeScaleDescription(Time.timeScale))); + DrawItem("Realtime Since Startup", Time.realtimeSinceStartup.ToString()); + DrawItem("Time Since Level Load", Time.timeSinceLevelLoad.ToString()); + DrawItem("Time", Time.time.ToString()); + DrawItem("Fixed Time", Time.fixedTime.ToString()); + DrawItem("Unscaled Time", Time.unscaledTime.ToString()); +#if UNITY_5_6_OR_NEWER + DrawItem("Fixed Unscaled Time", Time.fixedUnscaledTime.ToString()); +#endif + DrawItem("Delta Time", Time.deltaTime.ToString()); + DrawItem("Fixed Delta Time", Time.fixedDeltaTime.ToString()); + DrawItem("Unscaled Delta Time", Time.unscaledDeltaTime.ToString()); +#if UNITY_5_6_OR_NEWER + DrawItem("Fixed Unscaled Delta Time", Time.fixedUnscaledDeltaTime.ToString()); +#endif + DrawItem("Smooth Delta Time", Time.smoothDeltaTime.ToString()); + DrawItem("Maximum Delta Time", Time.maximumDeltaTime.ToString()); +#if UNITY_5_5_OR_NEWER + DrawItem("Maximum Particle Delta Time", Time.maximumParticleDeltaTime.ToString()); +#endif + DrawItem("Frame Count", Time.frameCount.ToString()); + DrawItem("Rendered Frame Count", Time.renderedFrameCount.ToString()); + DrawItem("Capture Framerate", Time.captureFramerate.ToString()); +#if UNITY_2019_2_OR_NEWER + DrawItem("Capture Delta Time", Time.captureDeltaTime.ToString()); +#endif +#if UNITY_5_6_OR_NEWER + DrawItem("In Fixed Time Step", Time.inFixedTimeStep.ToString()); +#endif + } + GUILayout.EndVertical(); + } + + private string GetTimeScaleDescription(float timeScale) + { + if (timeScale <= 0f) + { + return "Pause"; + } + + if (timeScale < 1f) + { + return "Slower"; + } + + if (timeScale > 1f) + { + return "Faster"; + } + + return "Normal"; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.TimeInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.TimeInformationWindow.cs.meta new file mode 100644 index 0000000..fd67ff3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.TimeInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8bdf40da7ffdc94ab9e39ba8daeaa3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.WebPlayerInformationWindow.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.WebPlayerInformationWindow.cs new file mode 100644 index 0000000..fce2e5f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.WebPlayerInformationWindow.cs @@ -0,0 +1,40 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + private sealed class WebPlayerInformationWindow : ScrollableDebuggerWindowBase + { + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Web Player Information"); + GUILayout.BeginVertical("box"); + { +#if !UNITY_2017_2_OR_NEWER + DrawItem("Is Web Player", Application.isWebPlayer.ToString()); +#endif + DrawItem("Absolute URL", Application.absoluteURL); +#if !UNITY_2017_2_OR_NEWER + DrawItem("Source Value", Application.srcValue); +#endif +#if !UNITY_2018_2_OR_NEWER + DrawItem("Streamed Bytes", Application.streamedBytes.ToString()); +#endif +#if UNITY_5_3 || UNITY_5_4 + DrawItem("Web Security Enabled", Application.webSecurityEnabled.ToString()); + DrawItem("Web Security Host URL", Application.webSecurityHostUrl.ToString()); +#endif + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.WebPlayerInformationWindow.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.WebPlayerInformationWindow.cs.meta new file mode 100644 index 0000000..a194fac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.WebPlayerInformationWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eea52d2ddd7a8804f956d4b9a2d67e8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.cs new file mode 100644 index 0000000..9c95be0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.cs @@ -0,0 +1,437 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Debugger; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 调试器组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Debugger")] + public sealed partial class DebuggerComponent : GameFrameworkComponent + { + /// + /// 默认调试器漂浮框大小。 + /// + internal static readonly Rect DefaultIconRect = new Rect(10f, 10f, 60f, 60f); + + /// + /// 默认调试器窗口大小。 + /// + internal static readonly Rect DefaultWindowRect = new Rect(10f, 10f, 640f, 480f); + + /// + /// 默认调试器窗口缩放比例。 + /// + internal static readonly float DefaultWindowScale = 1f; + + private static TextEditor s_TextEditor; + private IDebuggerManager m_DebuggerManager = null; + private Rect m_DragRect = new Rect(0f, 0f, float.MaxValue, 25f); + private Rect m_IconRect = DefaultIconRect; + private Rect m_WindowRect = DefaultWindowRect; + private float m_WindowScale = DefaultWindowScale; + + [SerializeField] + private GUISkin m_Skin = null; + + [SerializeField] + private DebuggerActiveWindowType m_ActiveWindow = DebuggerActiveWindowType.AlwaysOpen; + + [SerializeField] + private bool m_ShowFullWindow = false; + + [SerializeField] + private ConsoleWindow m_ConsoleWindow = new ConsoleWindow(); + + private SystemInformationWindow m_SystemInformationWindow = new SystemInformationWindow(); + private EnvironmentInformationWindow m_EnvironmentInformationWindow = new EnvironmentInformationWindow(); + private ScreenInformationWindow m_ScreenInformationWindow = new ScreenInformationWindow(); + private GraphicsInformationWindow m_GraphicsInformationWindow = new GraphicsInformationWindow(); + private InputSummaryInformationWindow m_InputSummaryInformationWindow = new InputSummaryInformationWindow(); + private InputTouchInformationWindow m_InputTouchInformationWindow = new InputTouchInformationWindow(); + private InputLocationInformationWindow m_InputLocationInformationWindow = new InputLocationInformationWindow(); + private InputAccelerationInformationWindow m_InputAccelerationInformationWindow = new InputAccelerationInformationWindow(); + private InputGyroscopeInformationWindow m_InputGyroscopeInformationWindow = new InputGyroscopeInformationWindow(); + private InputCompassInformationWindow m_InputCompassInformationWindow = new InputCompassInformationWindow(); + private PathInformationWindow m_PathInformationWindow = new PathInformationWindow(); + private SceneInformationWindow m_SceneInformationWindow = new SceneInformationWindow(); + private TimeInformationWindow m_TimeInformationWindow = new TimeInformationWindow(); + private QualityInformationWindow m_QualityInformationWindow = new QualityInformationWindow(); + private ProfilerInformationWindow m_ProfilerInformationWindow = new ProfilerInformationWindow(); + private WebPlayerInformationWindow m_WebPlayerInformationWindow = new WebPlayerInformationWindow(); + private RuntimeMemorySummaryWindow m_RuntimeMemorySummaryWindow = new RuntimeMemorySummaryWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryAllInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryTextureInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryMeshInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryMaterialInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryShaderInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryAnimationClipInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryAudioClipInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryFontInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryTextAssetInformationWindow = new RuntimeMemoryInformationWindow(); + private RuntimeMemoryInformationWindow m_RuntimeMemoryScriptableObjectInformationWindow = new RuntimeMemoryInformationWindow(); + private ObjectPoolInformationWindow m_ObjectPoolInformationWindow = new ObjectPoolInformationWindow(); + private ReferencePoolInformationWindow m_ReferencePoolInformationWindow = new ReferencePoolInformationWindow(); + private NetworkInformationWindow m_NetworkInformationWindow = new NetworkInformationWindow(); + private SettingsWindow m_SettingsWindow = new SettingsWindow(); + private OperationsWindow m_OperationsWindow = new OperationsWindow(); + + private FpsCounter m_FpsCounter = null; + + /// + /// 获取或设置调试器窗口是否激活。 + /// + public bool ActiveWindow + { + get + { + return m_DebuggerManager.ActiveWindow; + } + set + { + m_DebuggerManager.ActiveWindow = value; + enabled = value; + } + } + + /// + /// 获取或设置是否显示完整调试器界面。 + /// + public bool ShowFullWindow + { + get + { + return m_ShowFullWindow; + } + set + { + m_ShowFullWindow = value; + } + } + + /// + /// 获取或设置调试器漂浮框大小。 + /// + public Rect IconRect + { + get + { + return m_IconRect; + } + set + { + m_IconRect = value; + } + } + + /// + /// 获取或设置调试器窗口大小。 + /// + public Rect WindowRect + { + get + { + return m_WindowRect; + } + set + { + m_WindowRect = value; + } + } + + /// + /// 获取或设置调试器窗口缩放比例。 + /// + public float WindowScale + { + get + { + return m_WindowScale; + } + set + { + m_WindowScale = value; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + if(s_TextEditor == null) + { + s_TextEditor = new TextEditor(); + } + + m_DebuggerManager = GameFrameworkEntry.GetModule(); + if (m_DebuggerManager == null) + { + Log.Fatal("Debugger manager is invalid."); + return; + } + + m_FpsCounter = new FpsCounter(0.5f); + } + + private void Start() + { + RegisterDebuggerWindow("Console", m_ConsoleWindow); + RegisterDebuggerWindow("Information/System", m_SystemInformationWindow); + RegisterDebuggerWindow("Information/Environment", m_EnvironmentInformationWindow); + RegisterDebuggerWindow("Information/Screen", m_ScreenInformationWindow); + RegisterDebuggerWindow("Information/Graphics", m_GraphicsInformationWindow); + RegisterDebuggerWindow("Information/Input/Summary", m_InputSummaryInformationWindow); + RegisterDebuggerWindow("Information/Input/Touch", m_InputTouchInformationWindow); + RegisterDebuggerWindow("Information/Input/Location", m_InputLocationInformationWindow); + RegisterDebuggerWindow("Information/Input/Acceleration", m_InputAccelerationInformationWindow); + RegisterDebuggerWindow("Information/Input/Gyroscope", m_InputGyroscopeInformationWindow); + RegisterDebuggerWindow("Information/Input/Compass", m_InputCompassInformationWindow); + RegisterDebuggerWindow("Information/Other/Scene", m_SceneInformationWindow); + RegisterDebuggerWindow("Information/Other/Path", m_PathInformationWindow); + RegisterDebuggerWindow("Information/Other/Time", m_TimeInformationWindow); + RegisterDebuggerWindow("Information/Other/Quality", m_QualityInformationWindow); + RegisterDebuggerWindow("Information/Other/Web Player", m_WebPlayerInformationWindow); + RegisterDebuggerWindow("Profiler/Summary", m_ProfilerInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/Summary", m_RuntimeMemorySummaryWindow); + RegisterDebuggerWindow("Profiler/Memory/All", m_RuntimeMemoryAllInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/Texture", m_RuntimeMemoryTextureInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/Mesh", m_RuntimeMemoryMeshInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/Material", m_RuntimeMemoryMaterialInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/Shader", m_RuntimeMemoryShaderInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/AnimationClip", m_RuntimeMemoryAnimationClipInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/AudioClip", m_RuntimeMemoryAudioClipInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/Font", m_RuntimeMemoryFontInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/TextAsset", m_RuntimeMemoryTextAssetInformationWindow); + RegisterDebuggerWindow("Profiler/Memory/ScriptableObject", m_RuntimeMemoryScriptableObjectInformationWindow); + RegisterDebuggerWindow("Profiler/Object Pool", m_ObjectPoolInformationWindow); + RegisterDebuggerWindow("Profiler/Reference Pool", m_ReferencePoolInformationWindow); + RegisterDebuggerWindow("Profiler/Network", m_NetworkInformationWindow); + RegisterDebuggerWindow("Other/Settings", m_SettingsWindow); + RegisterDebuggerWindow("Other/Operations", m_OperationsWindow); + + switch (m_ActiveWindow) + { + case DebuggerActiveWindowType.AlwaysOpen: + ActiveWindow = true; + break; + + case DebuggerActiveWindowType.OnlyOpenWhenDevelopment: + ActiveWindow = Debug.isDebugBuild; + break; + + case DebuggerActiveWindowType.OnlyOpenInEditor: + ActiveWindow = Application.isEditor; + break; + + default: + ActiveWindow = false; + break; + } + } + + private void Update() + { + m_FpsCounter.Update(Time.deltaTime, Time.unscaledDeltaTime); + } + + private void OnGUI() + { + if (m_DebuggerManager == null || !m_DebuggerManager.ActiveWindow) + { + return; + } + + GUISkin cachedGuiSkin = GUI.skin; + Matrix4x4 cachedMatrix = GUI.matrix; + + GUI.skin = m_Skin; + GUI.matrix = Matrix4x4.Scale(new Vector3(m_WindowScale, m_WindowScale, 1f)); + + if (m_ShowFullWindow) + { + m_WindowRect = GUILayout.Window(0, m_WindowRect, DrawWindow, "GAME FRAMEWORK DEBUGGER"); + } + else + { + m_IconRect = GUILayout.Window(0, m_IconRect, DrawDebuggerWindowIcon, "DEBUGGER"); + } + + GUI.matrix = cachedMatrix; + GUI.skin = cachedGuiSkin; + } + + /// + /// 注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要注册的调试器窗口。 + /// 初始化调试器窗口参数。 + public void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow, params object[] args) + { + m_DebuggerManager.RegisterDebuggerWindow(path, debuggerWindow, args); + } + + /// + /// 解除注册调试器窗口。 + /// + /// 调试器窗口路径。 + /// 是否解除注册调试器窗口成功。 + public bool UnregisterDebuggerWindow(string path) + { + return m_DebuggerManager.UnregisterDebuggerWindow(path); + } + + /// + /// 获取调试器窗口。 + /// + /// 调试器窗口路径。 + /// 要获取的调试器窗口。 + public IDebuggerWindow GetDebuggerWindow(string path) + { + return m_DebuggerManager.GetDebuggerWindow(path); + } + + /// + /// 选中调试器窗口。 + /// + /// 调试器窗口路径。 + /// 是否成功选中调试器窗口。 + public bool SelectDebuggerWindow(string path) + { + return m_DebuggerManager.SelectDebuggerWindow(path); + } + + /// + /// 还原调试器窗口布局。 + /// + public void ResetLayout() + { + IconRect = DefaultIconRect; + WindowRect = DefaultWindowRect; + WindowScale = DefaultWindowScale; + } + + /// + /// 获取记录的所有日志。 + /// + /// 要获取的日志。 + public void GetRecentLogs(List results) + { + m_ConsoleWindow.GetRecentLogs(results); + } + + /// + /// 获取记录的最近日志。 + /// + /// 要获取的日志。 + /// 要获取最近日志的数量。 + public void GetRecentLogs(List results, int count) + { + m_ConsoleWindow.GetRecentLogs(results, count); + } + + private void DrawWindow(int windowId) + { + GUI.DragWindow(m_DragRect); + DrawDebuggerWindowGroup(m_DebuggerManager.DebuggerWindowRoot); + } + + private void DrawDebuggerWindowGroup(IDebuggerWindowGroup debuggerWindowGroup) + { + if (debuggerWindowGroup == null) + { + return; + } + + List names = new List(); + string[] debuggerWindowNames = debuggerWindowGroup.GetDebuggerWindowNames(); + for (int i = 0; i < debuggerWindowNames.Length; i++) + { + names.Add(Utility.Text.Format("{0}", debuggerWindowNames[i])); + } + + if (debuggerWindowGroup == m_DebuggerManager.DebuggerWindowRoot) + { + names.Add("Close"); + } + + int toolbarIndex = GUILayout.Toolbar(debuggerWindowGroup.SelectedIndex, names.ToArray(), GUILayout.Height(30f), GUILayout.MaxWidth(Screen.width)); + if (toolbarIndex >= debuggerWindowGroup.DebuggerWindowCount) + { + m_ShowFullWindow = false; + return; + } + + if (debuggerWindowGroup.SelectedWindow == null) + { + return; + } + + if (debuggerWindowGroup.SelectedIndex != toolbarIndex) + { + debuggerWindowGroup.SelectedWindow.OnLeave(); + debuggerWindowGroup.SelectedIndex = toolbarIndex; + debuggerWindowGroup.SelectedWindow.OnEnter(); + } + + IDebuggerWindowGroup subDebuggerWindowGroup = debuggerWindowGroup.SelectedWindow as IDebuggerWindowGroup; + if (subDebuggerWindowGroup != null) + { + DrawDebuggerWindowGroup(subDebuggerWindowGroup); + } + + debuggerWindowGroup.SelectedWindow.OnDraw(); + } + + private void DrawDebuggerWindowIcon(int windowId) + { + GUI.DragWindow(m_DragRect); + GUILayout.Space(5); + Color32 color = Color.white; + m_ConsoleWindow.RefreshCount(); + if (m_ConsoleWindow.FatalCount > 0) + { + color = m_ConsoleWindow.GetLogStringColor(LogType.Exception); + } + else if (m_ConsoleWindow.ErrorCount > 0) + { + color = m_ConsoleWindow.GetLogStringColor(LogType.Error); + } + else if (m_ConsoleWindow.WarningCount > 0) + { + color = m_ConsoleWindow.GetLogStringColor(LogType.Warning); + } + else + { + color = m_ConsoleWindow.GetLogStringColor(LogType.Log); + } + + string title = Utility.Text.Format("FPS: {4:F2}", color.r, color.g, color.b, color.a, m_FpsCounter.CurrentFps); + if (GUILayout.Button(title, GUILayout.Width(100f), GUILayout.Height(40f))) + { + m_ShowFullWindow = true; + } + } + + private static void CopyToClipboard(string content) + { + s_TextEditor.text = content; + s_TextEditor.OnFocus(); + s_TextEditor.Copy(); + s_TextEditor.text = string.Empty; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.cs.meta new file mode 100644 index 0000000..6288f5d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Debugger/DebuggerComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f05eaceeebe870a4595e51f998ed518b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download.meta new file mode 100644 index 0000000..f8c7788 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 565ef4330c482724588a750b62d2c533 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadAgentHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadAgentHelperBase.cs new file mode 100644 index 0000000..423c9dc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadAgentHelperBase.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Download; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 下载代理辅助器基类。 + /// + public abstract class DownloadAgentHelperBase : MonoBehaviour, IDownloadAgentHelper + { + /// + /// 范围不适用错误码。 + /// + protected const int RangeNotSatisfiableErrorCode = 416; + + /// + /// 下载代理辅助器更新数据流事件。 + /// + public abstract event EventHandler DownloadAgentHelperUpdateBytes; + + /// + /// 下载代理辅助器更新数据大小事件。 + /// + public abstract event EventHandler DownloadAgentHelperUpdateLength; + + /// + /// 下载代理辅助器完成事件。 + /// + public abstract event EventHandler DownloadAgentHelperComplete; + + /// + /// 下载代理辅助器错误事件。 + /// + public abstract event EventHandler DownloadAgentHelperError; + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 用户自定义数据。 + public abstract void Download(string downloadUri, object userData); + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 下载数据起始位置。 + /// 用户自定义数据。 + public abstract void Download(string downloadUri, long fromPosition, object userData); + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 下载数据起始位置。 + /// 下载数据结束位置。 + /// 用户自定义数据。 + public abstract void Download(string downloadUri, long fromPosition, long toPosition, object userData); + + /// + /// 重置下载代理辅助器。 + /// + public abstract void Reset(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadAgentHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadAgentHelperBase.cs.meta new file mode 100644 index 0000000..9fd9a0e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadAgentHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c6e60daac172714dba741765e1fdd97 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadComponent.cs new file mode 100644 index 0000000..cf633d7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadComponent.cs @@ -0,0 +1,409 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Download; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 下载组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Download")] + public sealed class DownloadComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + private const int OneMegaBytes = 1024 * 1024; + + private IDownloadManager m_DownloadManager = null; + private EventComponent m_EventComponent = null; + + [SerializeField] + private Transform m_InstanceRoot = null; + + [SerializeField] + private string m_DownloadAgentHelperTypeName = "UnityGameFramework.Runtime.UnityWebRequestDownloadAgentHelper"; + + [SerializeField] + private DownloadAgentHelperBase m_CustomDownloadAgentHelper = null; + + [SerializeField] + private int m_DownloadAgentHelperCount = 3; + + [SerializeField] + private float m_Timeout = 30f; + + [SerializeField] + private int m_FlushSize = OneMegaBytes; + + /// + /// 获取或设置下载是否被暂停。 + /// + public bool Paused + { + get + { + return m_DownloadManager.Paused; + } + set + { + m_DownloadManager.Paused = value; + } + } + + /// + /// 获取下载代理总数量。 + /// + public int TotalAgentCount + { + get + { + return m_DownloadManager.TotalAgentCount; + } + } + + /// + /// 获取可用下载代理数量。 + /// + public int FreeAgentCount + { + get + { + return m_DownloadManager.FreeAgentCount; + } + } + + /// + /// 获取工作中下载代理数量。 + /// + public int WorkingAgentCount + { + get + { + return m_DownloadManager.WorkingAgentCount; + } + } + + /// + /// 获取等待下载任务数量。 + /// + public int WaitingTaskCount + { + get + { + return m_DownloadManager.WaitingTaskCount; + } + } + + /// + /// 获取或设置下载超时时长,以秒为单位。 + /// + public float Timeout + { + get + { + return m_DownloadManager.Timeout; + } + set + { + m_DownloadManager.Timeout = m_Timeout = value; + } + } + + /// + /// 获取或设置将缓冲区写入磁盘的临界大小,仅当开启断点续传时有效。 + /// + public int FlushSize + { + get + { + return m_DownloadManager.FlushSize; + } + set + { + m_DownloadManager.FlushSize = m_FlushSize = value; + } + } + + /// + /// 获取当前下载速度。 + /// + public float CurrentSpeed + { + get + { + return m_DownloadManager.CurrentSpeed; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_DownloadManager = GameFrameworkEntry.GetModule(); + if (m_DownloadManager == null) + { + Log.Fatal("Download manager is invalid."); + return; + } + + m_DownloadManager.DownloadStart += OnDownloadStart; + m_DownloadManager.DownloadUpdate += OnDownloadUpdate; + m_DownloadManager.DownloadSuccess += OnDownloadSuccess; + m_DownloadManager.DownloadFailure += OnDownloadFailure; + m_DownloadManager.FlushSize = m_FlushSize; + m_DownloadManager.Timeout = m_Timeout; + } + + private void Start() + { + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (m_InstanceRoot == null) + { + m_InstanceRoot = new GameObject("Download Agent Instances").transform; + m_InstanceRoot.SetParent(gameObject.transform); + m_InstanceRoot.localScale = Vector3.one; + } + + for (int i = 0; i < m_DownloadAgentHelperCount; i++) + { + AddDownloadAgentHelper(i); + } + } + + /// + /// 根据下载任务的序列编号获取下载任务的信息。 + /// + /// 要获取信息的下载任务的序列编号。 + /// 下载任务的信息。 + public TaskInfo GetDownloadInfo(int serialId) + { + return m_DownloadManager.GetDownloadInfo(serialId); + } + + /// + /// 根据下载任务的标签获取下载任务的信息。 + /// + /// 要获取信息的下载任务的标签。 + /// 下载任务的信息。 + public TaskInfo[] GetDownloadInfos(string tag) + { + return m_DownloadManager.GetDownloadInfos(tag); + } + + /// + /// 根据下载任务的标签获取下载任务的信息。 + /// + /// 要获取信息的下载任务的标签。 + /// 下载任务的信息。 + public void GetDownloadInfos(string tag, List results) + { + m_DownloadManager.GetDownloadInfos(tag, results); + } + + /// + /// 获取所有下载任务的信息。 + /// + /// 所有下载任务的信息。 + public TaskInfo[] GetAllDownloadInfos() + { + return m_DownloadManager.GetAllDownloadInfos(); + } + + /// + /// 获取所有下载任务的信息。 + /// + /// 所有下载任务的信息。 + public void GetAllDownloadInfos(List results) + { + m_DownloadManager.GetAllDownloadInfos(results); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri) + { + return AddDownload(downloadPath, downloadUri, null, DefaultPriority, null); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, string tag) + { + return AddDownload(downloadPath, downloadUri, tag, DefaultPriority, null); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的优先级。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, int priority) + { + return AddDownload(downloadPath, downloadUri, null, priority, null); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, object userData) + { + return AddDownload(downloadPath, downloadUri, null, DefaultPriority, userData); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 下载任务的优先级。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, string tag, int priority) + { + return AddDownload(downloadPath, downloadUri, tag, priority, null); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, string tag, object userData) + { + return AddDownload(downloadPath, downloadUri, tag, DefaultPriority, userData); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的优先级。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, int priority, object userData) + { + return AddDownload(downloadPath, downloadUri, null, priority, userData); + } + + /// + /// 增加下载任务。 + /// + /// 下载后存放路径。 + /// 原始下载地址。 + /// 下载任务的标签。 + /// 下载任务的优先级。 + /// 用户自定义数据。 + /// 新增下载任务的序列编号。 + public int AddDownload(string downloadPath, string downloadUri, string tag, int priority, object userData) + { + return m_DownloadManager.AddDownload(downloadPath, downloadUri, tag, priority, userData); + } + + /// + /// 根据下载任务的序列编号移除下载任务。 + /// + /// 要移除下载任务的序列编号。 + /// 是否移除下载任务成功。 + public bool RemoveDownload(int serialId) + { + return m_DownloadManager.RemoveDownload(serialId); + } + + /// + /// 根据下载任务的标签移除下载任务。 + /// + /// 要移除下载任务的标签。 + /// 移除下载任务的数量。 + public int RemoveDownloads(string tag) + { + return m_DownloadManager.RemoveDownloads(tag); + } + + /// + /// 移除所有下载任务。 + /// + /// 移除下载任务的数量。 + public int RemoveAllDownloads() + { + return m_DownloadManager.RemoveAllDownloads(); + } + + /// + /// 增加下载代理辅助器。 + /// + /// 下载代理辅助器索引。 + private void AddDownloadAgentHelper(int index) + { + DownloadAgentHelperBase downloadAgentHelper = Helper.CreateHelper(m_DownloadAgentHelperTypeName, m_CustomDownloadAgentHelper, index); + if (downloadAgentHelper == null) + { + Log.Error("Can not create download agent helper."); + return; + } + + downloadAgentHelper.name = Utility.Text.Format("Download Agent Helper - {0}", index); + Transform transform = downloadAgentHelper.transform; + transform.SetParent(m_InstanceRoot); + transform.localScale = Vector3.one; + + m_DownloadManager.AddDownloadAgentHelper(downloadAgentHelper); + } + + private void OnDownloadStart(object sender, GameFramework.Download.DownloadStartEventArgs e) + { + m_EventComponent.Fire(this, DownloadStartEventArgs.Create(e)); + } + + private void OnDownloadUpdate(object sender, GameFramework.Download.DownloadUpdateEventArgs e) + { + m_EventComponent.Fire(this, DownloadUpdateEventArgs.Create(e)); + } + + private void OnDownloadSuccess(object sender, GameFramework.Download.DownloadSuccessEventArgs e) + { + m_EventComponent.Fire(this, DownloadSuccessEventArgs.Create(e)); + } + + private void OnDownloadFailure(object sender, GameFramework.Download.DownloadFailureEventArgs e) + { + Log.Warning("Download failure, download serial id '{0}', download path '{1}', download uri '{2}', error message '{3}'.", e.SerialId, e.DownloadPath, e.DownloadUri, e.ErrorMessage); + m_EventComponent.Fire(this, DownloadFailureEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadComponent.cs.meta new file mode 100644 index 0000000..7460354 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9259de0854ba2624aa59aca15c6af063 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadFailureEventArgs.cs new file mode 100644 index 0000000..f9cbbec --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadFailureEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 下载失败事件。 + /// + public sealed class DownloadFailureEventArgs : GameEventArgs + { + /// + /// 下载失败事件编号。 + /// + public static readonly int EventId = typeof(DownloadFailureEventArgs).GetHashCode(); + + /// + /// 初始化下载失败事件的新实例。 + /// + public DownloadFailureEventArgs() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取下载失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取下载任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建下载失败事件。 + /// + /// 内部事件。 + /// 创建的下载失败事件。 + public static DownloadFailureEventArgs Create(GameFramework.Download.DownloadFailureEventArgs e) + { + DownloadFailureEventArgs downloadFailureEventArgs = ReferencePool.Acquire(); + downloadFailureEventArgs.SerialId = e.SerialId; + downloadFailureEventArgs.DownloadPath = e.DownloadPath; + downloadFailureEventArgs.DownloadUri = e.DownloadUri; + downloadFailureEventArgs.ErrorMessage = e.ErrorMessage; + downloadFailureEventArgs.UserData = e.UserData; + return downloadFailureEventArgs; + } + + /// + /// 清理下载失败事件。 + /// + public override void Clear() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadFailureEventArgs.cs.meta new file mode 100644 index 0000000..1500aa8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b3227ba2aea8444397bb69d11e667fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadStartEventArgs.cs new file mode 100644 index 0000000..6acfed8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadStartEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 下载开始事件。 + /// + public sealed class DownloadStartEventArgs : GameEventArgs + { + /// + /// 下载开始事件编号。 + /// + public static readonly int EventId = typeof(DownloadStartEventArgs).GetHashCode(); + + /// + /// 初始化下载开始事件的新实例。 + /// + public DownloadStartEventArgs() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + + /// + /// 获取下载开始事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取下载任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前大小。 + /// + public long CurrentLength + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建下载开始事件。 + /// + /// 内部事件。 + /// 创建的下载开始事件。 + public static DownloadStartEventArgs Create(GameFramework.Download.DownloadStartEventArgs e) + { + DownloadStartEventArgs downloadStartEventArgs = ReferencePool.Acquire(); + downloadStartEventArgs.SerialId = e.SerialId; + downloadStartEventArgs.DownloadPath = e.DownloadPath; + downloadStartEventArgs.DownloadUri = e.DownloadUri; + downloadStartEventArgs.CurrentLength = e.CurrentLength; + downloadStartEventArgs.UserData = e.UserData; + return downloadStartEventArgs; + } + + /// + /// 清理下载开始事件。 + /// + public override void Clear() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadStartEventArgs.cs.meta new file mode 100644 index 0000000..78ad77f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee21721798f32c7459a235204468db6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadSuccessEventArgs.cs new file mode 100644 index 0000000..6db89e6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadSuccessEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 下载成功事件。 + /// + public sealed class DownloadSuccessEventArgs : GameEventArgs + { + /// + /// 下载成功事件编号。 + /// + public static readonly int EventId = typeof(DownloadSuccessEventArgs).GetHashCode(); + + /// + /// 初始化下载成功事件的新实例。 + /// + public DownloadSuccessEventArgs() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + + /// + /// 获取下载成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取下载任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前大小。 + /// + public long CurrentLength + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建下载成功事件。 + /// + /// 内部事件。 + /// 创建的下载成功事件。 + public static DownloadSuccessEventArgs Create(GameFramework.Download.DownloadSuccessEventArgs e) + { + DownloadSuccessEventArgs downloadSuccessEventArgs = ReferencePool.Acquire(); + downloadSuccessEventArgs.SerialId = e.SerialId; + downloadSuccessEventArgs.DownloadPath = e.DownloadPath; + downloadSuccessEventArgs.DownloadUri = e.DownloadUri; + downloadSuccessEventArgs.CurrentLength = e.CurrentLength; + downloadSuccessEventArgs.UserData = e.UserData; + return downloadSuccessEventArgs; + } + + /// + /// 清理下载成功事件。 + /// + public override void Clear() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadSuccessEventArgs.cs.meta new file mode 100644 index 0000000..3500639 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0d6ca8ee116c7c43b319992b5a4cdbf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadUpdateEventArgs.cs new file mode 100644 index 0000000..6e35ab9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadUpdateEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 下载更新事件。 + /// + public sealed class DownloadUpdateEventArgs : GameEventArgs + { + /// + /// 下载更新事件编号。 + /// + public static readonly int EventId = typeof(DownloadUpdateEventArgs).GetHashCode(); + + /// + /// 初始化下载更新事件的新实例。 + /// + public DownloadUpdateEventArgs() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + + /// + /// 获取下载更新事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取下载任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前大小。 + /// + public long CurrentLength + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建下载更新事件。 + /// + /// 内部事件。 + /// 创建的下载更新事件。 + public static DownloadUpdateEventArgs Create(GameFramework.Download.DownloadUpdateEventArgs e) + { + DownloadUpdateEventArgs downloadUpdateEventArgs = ReferencePool.Acquire(); + downloadUpdateEventArgs.SerialId = e.SerialId; + downloadUpdateEventArgs.DownloadPath = e.DownloadPath; + downloadUpdateEventArgs.DownloadUri = e.DownloadUri; + downloadUpdateEventArgs.CurrentLength = e.CurrentLength; + downloadUpdateEventArgs.UserData = e.UserData; + return downloadUpdateEventArgs; + } + + /// + /// 清理下载更新事件。 + /// + public override void Clear() + { + SerialId = 0; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0L; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadUpdateEventArgs.cs.meta new file mode 100644 index 0000000..9e7eb8e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/DownloadUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da30c910f3da16f4cb29770ee035496b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.DownloadHandler.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.DownloadHandler.cs new file mode 100644 index 0000000..060c332 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.DownloadHandler.cs @@ -0,0 +1,48 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Download; +using System; +#if UNITY_5_4_OR_NEWER +using UnityEngine.Networking; +#else +using UnityEngine.Experimental.Networking; +#endif + +namespace UnityGameFramework.Runtime +{ + public partial class UnityWebRequestDownloadAgentHelper : DownloadAgentHelperBase, IDisposable + { + private sealed class DownloadHandler : DownloadHandlerScript + { + private readonly UnityWebRequestDownloadAgentHelper m_Owner; + + public DownloadHandler(UnityWebRequestDownloadAgentHelper owner) + : base(owner.m_CachedBytes) + { + m_Owner = owner; + } + + protected override bool ReceiveData(byte[] data, int dataLength) + { + if (m_Owner != null && m_Owner.m_UnityWebRequest != null && dataLength > 0) + { + DownloadAgentHelperUpdateBytesEventArgs downloadAgentHelperUpdateBytesEventArgs = DownloadAgentHelperUpdateBytesEventArgs.Create(data, 0, dataLength); + m_Owner.m_DownloadAgentHelperUpdateBytesEventHandler(this, downloadAgentHelperUpdateBytesEventArgs); + ReferencePool.Release(downloadAgentHelperUpdateBytesEventArgs); + + DownloadAgentHelperUpdateLengthEventArgs downloadAgentHelperUpdateLengthEventArgs = DownloadAgentHelperUpdateLengthEventArgs.Create(dataLength); + m_Owner.m_DownloadAgentHelperUpdateLengthEventHandler(this, downloadAgentHelperUpdateLengthEventArgs); + ReferencePool.Release(downloadAgentHelperUpdateLengthEventArgs); + } + + return base.ReceiveData(data, dataLength); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.DownloadHandler.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.DownloadHandler.cs.meta new file mode 100644 index 0000000..738d8cb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.DownloadHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc6b62e45f7a521499fdd86e1e9071df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.cs new file mode 100644 index 0000000..4f01fa8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.cs @@ -0,0 +1,248 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Download; +using System; +#if UNITY_5_4_OR_NEWER +using UnityEngine.Networking; +#else +using UnityEngine.Experimental.Networking; +#endif +using Utility = GameFramework.Utility; + +namespace UnityGameFramework.Runtime +{ + /// + /// 使用 UnityWebRequest 实现的下载代理辅助器。 + /// + public partial class UnityWebRequestDownloadAgentHelper : DownloadAgentHelperBase, IDisposable + { + private const int CachedBytesLength = 0x1000; + private readonly byte[] m_CachedBytes = new byte[CachedBytesLength]; + + private UnityWebRequest m_UnityWebRequest = null; + private bool m_Disposed = false; + + private EventHandler m_DownloadAgentHelperUpdateBytesEventHandler = null; + private EventHandler m_DownloadAgentHelperUpdateLengthEventHandler = null; + private EventHandler m_DownloadAgentHelperCompleteEventHandler = null; + private EventHandler m_DownloadAgentHelperErrorEventHandler = null; + + /// + /// 下载代理辅助器更新数据流事件。 + /// + public override event EventHandler DownloadAgentHelperUpdateBytes + { + add + { + m_DownloadAgentHelperUpdateBytesEventHandler += value; + } + remove + { + m_DownloadAgentHelperUpdateBytesEventHandler -= value; + } + } + + /// + /// 下载代理辅助器更新数据大小事件。 + /// + public override event EventHandler DownloadAgentHelperUpdateLength + { + add + { + m_DownloadAgentHelperUpdateLengthEventHandler += value; + } + remove + { + m_DownloadAgentHelperUpdateLengthEventHandler -= value; + } + } + + /// + /// 下载代理辅助器完成事件。 + /// + public override event EventHandler DownloadAgentHelperComplete + { + add + { + m_DownloadAgentHelperCompleteEventHandler += value; + } + remove + { + m_DownloadAgentHelperCompleteEventHandler -= value; + } + } + + /// + /// 下载代理辅助器错误事件。 + /// + public override event EventHandler DownloadAgentHelperError + { + add + { + m_DownloadAgentHelperErrorEventHandler += value; + } + remove + { + m_DownloadAgentHelperErrorEventHandler -= value; + } + } + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 用户自定义数据。 + public override void Download(string downloadUri, object userData) + { + if (m_DownloadAgentHelperUpdateBytesEventHandler == null || m_DownloadAgentHelperUpdateLengthEventHandler == null || m_DownloadAgentHelperCompleteEventHandler == null || m_DownloadAgentHelperErrorEventHandler == null) + { + Log.Fatal("Download agent helper handler is invalid."); + return; + } + + m_UnityWebRequest = new UnityWebRequest(downloadUri); + m_UnityWebRequest.downloadHandler = new DownloadHandler(this); +#if UNITY_2017_2_OR_NEWER + m_UnityWebRequest.SendWebRequest(); +#else + m_UnityWebRequest.Send(); +#endif + } + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 下载数据起始位置。 + /// 用户自定义数据。 + public override void Download(string downloadUri, long fromPosition, object userData) + { + if (m_DownloadAgentHelperUpdateBytesEventHandler == null || m_DownloadAgentHelperUpdateLengthEventHandler == null || m_DownloadAgentHelperCompleteEventHandler == null || m_DownloadAgentHelperErrorEventHandler == null) + { + Log.Fatal("Download agent helper handler is invalid."); + return; + } + + m_UnityWebRequest = new UnityWebRequest(downloadUri); + m_UnityWebRequest.SetRequestHeader("Range", Utility.Text.Format("bytes={0}-", fromPosition)); + m_UnityWebRequest.downloadHandler = new DownloadHandler(this); +#if UNITY_2017_2_OR_NEWER + m_UnityWebRequest.SendWebRequest(); +#else + m_UnityWebRequest.Send(); +#endif + } + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 下载数据起始位置。 + /// 下载数据结束位置。 + /// 用户自定义数据。 + public override void Download(string downloadUri, long fromPosition, long toPosition, object userData) + { + if (m_DownloadAgentHelperUpdateBytesEventHandler == null || m_DownloadAgentHelperUpdateLengthEventHandler == null || m_DownloadAgentHelperCompleteEventHandler == null || m_DownloadAgentHelperErrorEventHandler == null) + { + Log.Fatal("Download agent helper handler is invalid."); + return; + } + + m_UnityWebRequest = new UnityWebRequest(downloadUri); + m_UnityWebRequest.SetRequestHeader("Range", Utility.Text.Format("bytes={0}-{1}", fromPosition, toPosition)); + m_UnityWebRequest.downloadHandler = new DownloadHandler(this); +#if UNITY_2017_2_OR_NEWER + m_UnityWebRequest.SendWebRequest(); +#else + m_UnityWebRequest.Send(); +#endif + } + + /// + /// 重置下载代理辅助器。 + /// + public override void Reset() + { + if (m_UnityWebRequest != null) + { + m_UnityWebRequest.Abort(); + m_UnityWebRequest.Dispose(); + m_UnityWebRequest = null; + } + + Array.Clear(m_CachedBytes, 0, CachedBytesLength); + } + + /// + /// 释放资源。 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 释放资源。 + /// + /// 释放资源标记。 + protected virtual void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_UnityWebRequest != null) + { + m_UnityWebRequest.Dispose(); + m_UnityWebRequest = null; + } + } + + m_Disposed = true; + } + + private void Update() + { + if (m_UnityWebRequest == null) + { + return; + } + + if (!m_UnityWebRequest.isDone) + { + return; + } + + bool isError = false; +#if UNITY_2020_2_OR_NEWER + isError = m_UnityWebRequest.result != UnityWebRequest.Result.Success; +#elif UNITY_2017_1_OR_NEWER + isError = m_UnityWebRequest.isNetworkError || m_UnityWebRequest.isHttpError; +#else + isError = m_UnityWebRequest.isError; +#endif + if (isError) + { + DownloadAgentHelperErrorEventArgs downloadAgentHelperErrorEventArgs = DownloadAgentHelperErrorEventArgs.Create(m_UnityWebRequest.responseCode == RangeNotSatisfiableErrorCode, m_UnityWebRequest.error); + m_DownloadAgentHelperErrorEventHandler(this, downloadAgentHelperErrorEventArgs); + ReferencePool.Release(downloadAgentHelperErrorEventArgs); + } + else + { + DownloadAgentHelperCompleteEventArgs downloadAgentHelperCompleteEventArgs = DownloadAgentHelperCompleteEventArgs.Create((long)m_UnityWebRequest.downloadedBytes); + m_DownloadAgentHelperCompleteEventHandler(this, downloadAgentHelperCompleteEventArgs); + ReferencePool.Release(downloadAgentHelperCompleteEventArgs); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.cs.meta new file mode 100644 index 0000000..c595a0a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/UnityWebRequestDownloadAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a19b280dcc736764fb78ce804a6c4d88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/WWWDownloadAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/WWWDownloadAgentHelper.cs new file mode 100644 index 0000000..8daccc1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/WWWDownloadAgentHelper.cs @@ -0,0 +1,246 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +#if !UNITY_2018_3_OR_NEWER + +using GameFramework; +using GameFramework.Download; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// WWW 下载代理辅助器。 + /// + public class WWWDownloadAgentHelper : DownloadAgentHelperBase, IDisposable + { + private WWW m_WWW = null; + private int m_LastDownloadedSize = 0; + private bool m_Disposed = false; + + private EventHandler m_DownloadAgentHelperUpdateBytesEventHandler = null; + private EventHandler m_DownloadAgentHelperUpdateLengthEventHandler = null; + private EventHandler m_DownloadAgentHelperCompleteEventHandler = null; + private EventHandler m_DownloadAgentHelperErrorEventHandler = null; + + /// + /// 下载代理辅助器更新数据流事件。 + /// + public override event EventHandler DownloadAgentHelperUpdateBytes + { + add + { + m_DownloadAgentHelperUpdateBytesEventHandler += value; + } + remove + { + m_DownloadAgentHelperUpdateBytesEventHandler -= value; + } + } + + /// + /// 下载代理辅助器更新数据大小事件。 + /// + public override event EventHandler DownloadAgentHelperUpdateLength + { + add + { + m_DownloadAgentHelperUpdateLengthEventHandler += value; + } + remove + { + m_DownloadAgentHelperUpdateLengthEventHandler -= value; + } + } + + /// + /// 下载代理辅助器完成事件。 + /// + public override event EventHandler DownloadAgentHelperComplete + { + add + { + m_DownloadAgentHelperCompleteEventHandler += value; + } + remove + { + m_DownloadAgentHelperCompleteEventHandler -= value; + } + } + + /// + /// 下载代理辅助器错误事件。 + /// + public override event EventHandler DownloadAgentHelperError + { + add + { + m_DownloadAgentHelperErrorEventHandler += value; + } + remove + { + m_DownloadAgentHelperErrorEventHandler -= value; + } + } + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 用户自定义数据。 + public override void Download(string downloadUri, object userData) + { + if (m_DownloadAgentHelperUpdateBytesEventHandler == null || m_DownloadAgentHelperUpdateLengthEventHandler == null || m_DownloadAgentHelperCompleteEventHandler == null || m_DownloadAgentHelperErrorEventHandler == null) + { + Log.Fatal("Download agent helper handler is invalid."); + return; + } + + m_WWW = new WWW(downloadUri); + } + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 下载数据起始位置。 + /// 用户自定义数据。 + public override void Download(string downloadUri, long fromPosition, object userData) + { + if (m_DownloadAgentHelperUpdateBytesEventHandler == null || m_DownloadAgentHelperUpdateLengthEventHandler == null || m_DownloadAgentHelperCompleteEventHandler == null || m_DownloadAgentHelperErrorEventHandler == null) + { + Log.Fatal("Download agent helper handler is invalid."); + return; + } + + Dictionary header = new Dictionary + { + { "Range", Utility.Text.Format("bytes={0}-", fromPosition) } + }; + + m_WWW = new WWW(downloadUri, null, header); + } + + /// + /// 通过下载代理辅助器下载指定地址的数据。 + /// + /// 下载地址。 + /// 下载数据起始位置。 + /// 下载数据结束位置。 + /// 用户自定义数据。 + public override void Download(string downloadUri, long fromPosition, long toPosition, object userData) + { + if (m_DownloadAgentHelperUpdateBytesEventHandler == null || m_DownloadAgentHelperUpdateLengthEventHandler == null || m_DownloadAgentHelperCompleteEventHandler == null || m_DownloadAgentHelperErrorEventHandler == null) + { + Log.Fatal("Download agent helper handler is invalid."); + return; + } + + Dictionary header = new Dictionary + { + { "Range", Utility.Text.Format("bytes={0}-{1}", fromPosition, toPosition) } + }; + + m_WWW = new WWW(downloadUri, null, header); + } + + /// + /// 重置下载代理辅助器。 + /// + public override void Reset() + { + if (m_WWW != null) + { + m_WWW.Dispose(); + m_WWW = null; + } + + m_LastDownloadedSize = 0; + } + + /// + /// 释放资源。 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 释放资源。 + /// + /// 释放资源标记。 + protected virtual void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_WWW != null) + { + m_WWW.Dispose(); + m_WWW = null; + } + } + + m_Disposed = true; + } + + private void Update() + { + if (m_WWW == null) + { + return; + } + + int deltaLength = m_WWW.bytesDownloaded - m_LastDownloadedSize; + if (deltaLength > 0) + { + m_LastDownloadedSize = m_WWW.bytesDownloaded; + DownloadAgentHelperUpdateLengthEventArgs downloadAgentHelperUpdateLengthEventArgs = DownloadAgentHelperUpdateLengthEventArgs.Create(deltaLength); + m_DownloadAgentHelperUpdateLengthEventHandler(this, downloadAgentHelperUpdateLengthEventArgs); + ReferencePool.Release(downloadAgentHelperUpdateLengthEventArgs); + } + + if (m_WWW == null) + { + return; + } + + if (!m_WWW.isDone) + { + return; + } + + if (!string.IsNullOrEmpty(m_WWW.error)) + { + DownloadAgentHelperErrorEventArgs dodwnloadAgentHelperErrorEventArgs = DownloadAgentHelperErrorEventArgs.Create(m_WWW.error.StartsWith(RangeNotSatisfiableErrorCode.ToString(), StringComparison.Ordinal), m_WWW.error); + m_DownloadAgentHelperErrorEventHandler(this, dodwnloadAgentHelperErrorEventArgs); + ReferencePool.Release(dodwnloadAgentHelperErrorEventArgs); + } + else + { + byte[] bytes = m_WWW.bytes; + DownloadAgentHelperUpdateBytesEventArgs downloadAgentHelperUpdateBytesEventArgs = DownloadAgentHelperUpdateBytesEventArgs.Create(bytes, 0, bytes.Length); + m_DownloadAgentHelperUpdateBytesEventHandler(this, downloadAgentHelperUpdateBytesEventArgs); + ReferencePool.Release(downloadAgentHelperUpdateBytesEventArgs); + + DownloadAgentHelperCompleteEventArgs downloadAgentHelperCompleteEventArgs = DownloadAgentHelperCompleteEventArgs.Create(bytes.LongLength); + m_DownloadAgentHelperCompleteEventHandler(this, downloadAgentHelperCompleteEventArgs); + ReferencePool.Release(downloadAgentHelperCompleteEventArgs); + } + } + } +} + +#endif diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/WWWDownloadAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/WWWDownloadAgentHelper.cs.meta new file mode 100644 index 0000000..67dc31b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Download/WWWDownloadAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30217a4100363014a9c8c671b5848a61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity.meta new file mode 100644 index 0000000..633fe4e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c847fbba6525ec643a5fbb113b54eaf0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/AttachEntityInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/AttachEntityInfo.cs new file mode 100644 index 0000000..c8e3fff --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/AttachEntityInfo.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + internal sealed class AttachEntityInfo : IReference + { + private Transform m_ParentTransform; + private object m_UserData; + + public AttachEntityInfo() + { + m_ParentTransform = null; + m_UserData = null; + } + + public Transform ParentTransform + { + get + { + return m_ParentTransform; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + + public static AttachEntityInfo Create(Transform parentTransform, object userData) + { + AttachEntityInfo attachEntityInfo = ReferencePool.Acquire(); + attachEntityInfo.m_ParentTransform = parentTransform; + attachEntityInfo.m_UserData = userData; + return attachEntityInfo; + } + + public void Clear() + { + m_ParentTransform = null; + m_UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/AttachEntityInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/AttachEntityInfo.cs.meta new file mode 100644 index 0000000..15fee8c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/AttachEntityInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93ee8133074b5234da08e1308a55efb2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityGroupHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityGroupHelper.cs new file mode 100644 index 0000000..cb123db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityGroupHelper.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认实体组辅助器。 + /// + public class DefaultEntityGroupHelper : EntityGroupHelperBase + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityGroupHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityGroupHelper.cs.meta new file mode 100644 index 0000000..c56b639 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityGroupHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2eae0b22de94ba442b482bff7fab17ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityHelper.cs new file mode 100644 index 0000000..a22e066 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityHelper.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Entity; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认实体辅助器。 + /// + public class DefaultEntityHelper : EntityHelperBase + { + private ResourceComponent m_ResourceComponent = null; + + /// + /// 实例化实体。 + /// + /// 要实例化的实体资源。 + /// 实例化后的实体。 + public override object InstantiateEntity(object entityAsset) + { + return Instantiate((Object)entityAsset); + } + + /// + /// 创建实体。 + /// + /// 实体实例。 + /// 实体所属的实体组。 + /// 用户自定义数据。 + /// 实体。 + public override IEntity CreateEntity(object entityInstance, IEntityGroup entityGroup, object userData) + { + GameObject gameObject = entityInstance as GameObject; + if (gameObject == null) + { + Log.Error("Entity instance is invalid."); + return null; + } + + Transform transform = gameObject.transform; + transform.SetParent(((MonoBehaviour)entityGroup.Helper).transform); + + return gameObject.GetOrAddComponent(); + } + + /// + /// 释放实体。 + /// + /// 要释放的实体资源。 + /// 要释放的实体实例。 + public override void ReleaseEntity(object entityAsset, object entityInstance) + { + m_ResourceComponent.UnloadAsset(entityAsset); + Destroy((Object)entityInstance); + } + + private void Start() + { + m_ResourceComponent = GameEntry.GetComponent(); + if (m_ResourceComponent == null) + { + Log.Fatal("Resource component is invalid."); + return; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityHelper.cs.meta new file mode 100644 index 0000000..76a3eea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/DefaultEntityHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b0ffb61c68e948498fa57c1901f0001 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/Entity.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/Entity.cs new file mode 100644 index 0000000..9a3e320 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/Entity.cs @@ -0,0 +1,280 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Entity; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 实体。 + /// + public sealed class Entity : MonoBehaviour, IEntity + { + private int m_Id; + private string m_EntityAssetName; + private IEntityGroup m_EntityGroup; + private EntityLogic m_EntityLogic; + + /// + /// 获取实体编号。 + /// + public int Id + { + get + { + return m_Id; + } + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get + { + return m_EntityAssetName; + } + } + + /// + /// 获取实体实例。 + /// + public object Handle + { + get + { + return gameObject; + } + } + + /// + /// 获取实体所属的实体组。 + /// + public IEntityGroup EntityGroup + { + get + { + return m_EntityGroup; + } + } + + /// + /// 获取实体逻辑。 + /// + public EntityLogic Logic + { + get + { + return m_EntityLogic; + } + } + + /// + /// 实体初始化。 + /// + /// 实体编号。 + /// 实体资源名称。 + /// 实体所属的实体组。 + /// 是否是新实例。 + /// 用户自定义数据。 + public void OnInit(int entityId, string entityAssetName, IEntityGroup entityGroup, bool isNewInstance, object userData) + { + m_Id = entityId; + m_EntityAssetName = entityAssetName; + if (isNewInstance) + { + m_EntityGroup = entityGroup; + } + else if (m_EntityGroup != entityGroup) + { + Log.Error("Entity group is inconsistent for non-new-instance entity."); + return; + } + + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + Type entityLogicType = showEntityInfo.EntityLogicType; + if (entityLogicType == null) + { + Log.Error("Entity logic type is invalid."); + return; + } + + if (m_EntityLogic != null) + { + if (m_EntityLogic.GetType() == entityLogicType) + { + m_EntityLogic.enabled = true; + return; + } + + Destroy(m_EntityLogic); + m_EntityLogic = null; + } + + m_EntityLogic = gameObject.AddComponent(entityLogicType) as EntityLogic; + if (m_EntityLogic == null) + { + Log.Error("Entity '{0}' can not add entity logic.", entityAssetName); + return; + } + + try + { + m_EntityLogic.OnInit(showEntityInfo.UserData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnInit with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + } + + /// + /// 实体回收。 + /// + public void OnRecycle() + { + try + { + m_EntityLogic.OnRecycle(); + m_EntityLogic.enabled = false; + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnRecycle with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + + m_Id = 0; + } + + /// + /// 实体显示。 + /// + /// 用户自定义数据。 + public void OnShow(object userData) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)userData; + try + { + m_EntityLogic.OnShow(showEntityInfo.UserData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnShow with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + } + + /// + /// 实体隐藏。 + /// + /// 是否是关闭实体管理器时触发。 + /// 用户自定义数据。 + public void OnHide(bool isShutdown, object userData) + { + try + { + m_EntityLogic.OnHide(isShutdown, userData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnHide with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + } + + /// + /// 实体附加子实体。 + /// + /// 附加的子实体。 + /// 用户自定义数据。 + public void OnAttached(IEntity childEntity, object userData) + { + AttachEntityInfo attachEntityInfo = (AttachEntityInfo)userData; + try + { + m_EntityLogic.OnAttached(((Entity)childEntity).Logic, attachEntityInfo.ParentTransform, attachEntityInfo.UserData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnAttached with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + } + + /// + /// 实体解除子实体。 + /// + /// 解除的子实体。 + /// 用户自定义数据。 + public void OnDetached(IEntity childEntity, object userData) + { + try + { + m_EntityLogic.OnDetached(((Entity)childEntity).Logic, userData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnDetached with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + } + + /// + /// 实体附加子实体。 + /// + /// 被附加的父实体。 + /// 用户自定义数据。 + public void OnAttachTo(IEntity parentEntity, object userData) + { + AttachEntityInfo attachEntityInfo = (AttachEntityInfo)userData; + try + { + m_EntityLogic.OnAttachTo(((Entity)parentEntity).Logic, attachEntityInfo.ParentTransform, attachEntityInfo.UserData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnAttachTo with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + + ReferencePool.Release(attachEntityInfo); + } + + /// + /// 实体解除子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + public void OnDetachFrom(IEntity parentEntity, object userData) + { + try + { + m_EntityLogic.OnDetachFrom(((Entity)parentEntity).Logic, userData); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnDetachFrom with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + } + + /// + /// 实体轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + try + { + m_EntityLogic.OnUpdate(elapseSeconds, realElapseSeconds); + } + catch (Exception exception) + { + Log.Error("Entity '[{0}]{1}' OnUpdate with exception '{2}'.", m_Id, m_EntityAssetName, exception); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/Entity.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/Entity.cs.meta new file mode 100644 index 0000000..85e287d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/Entity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bac1e67b934ef0944b6de46554cf5042 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.EntityGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.EntityGroup.cs new file mode 100644 index 0000000..1ffe103 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.EntityGroup.cs @@ -0,0 +1,74 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class EntityComponent : GameFrameworkComponent + { + [Serializable] + private sealed class EntityGroup + { + [SerializeField] + private string m_Name = null; + + [SerializeField] + private float m_InstanceAutoReleaseInterval = 60f; + + [SerializeField] + private int m_InstanceCapacity = 16; + + [SerializeField] + private float m_InstanceExpireTime = 60f; + + [SerializeField] + private int m_InstancePriority = 0; + + public string Name + { + get + { + return m_Name; + } + } + + public float InstanceAutoReleaseInterval + { + get + { + return m_InstanceAutoReleaseInterval; + } + } + + public int InstanceCapacity + { + get + { + return m_InstanceCapacity; + } + } + + public float InstanceExpireTime + { + get + { + return m_InstanceExpireTime; + } + } + + public int InstancePriority + { + get + { + return m_InstancePriority; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.EntityGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.EntityGroup.cs.meta new file mode 100644 index 0000000..c12b4fb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.EntityGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d93d1ae840acb2f449ac5f5cad2d0259 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.cs new file mode 100644 index 0000000..6df3130 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.cs @@ -0,0 +1,1146 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Entity; +using GameFramework.ObjectPool; +using GameFramework.Resource; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 实体组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Entity")] + public sealed partial class EntityComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + + private IEntityManager m_EntityManager = null; + private EventComponent m_EventComponent = null; + + private readonly List m_InternalEntityResults = new List(); + + [SerializeField] + private bool m_EnableShowEntityUpdateEvent = false; + + [SerializeField] + private bool m_EnableShowEntityDependencyAssetEvent = false; + + [SerializeField] + private Transform m_InstanceRoot = null; + + [SerializeField] + private string m_EntityHelperTypeName = "UnityGameFramework.Runtime.DefaultEntityHelper"; + + [SerializeField] + private EntityHelperBase m_CustomEntityHelper = null; + + [SerializeField] + private string m_EntityGroupHelperTypeName = "UnityGameFramework.Runtime.DefaultEntityGroupHelper"; + + [SerializeField] + private EntityGroupHelperBase m_CustomEntityGroupHelper = null; + + [SerializeField] + private EntityGroup[] m_EntityGroups = null; + + /// + /// 获取实体数量。 + /// + public int EntityCount + { + get + { + return m_EntityManager.EntityCount; + } + } + + /// + /// 获取实体组数量。 + /// + public int EntityGroupCount + { + get + { + return m_EntityManager.EntityGroupCount; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_EntityManager = GameFrameworkEntry.GetModule(); + if (m_EntityManager == null) + { + Log.Fatal("Entity manager is invalid."); + return; + } + + m_EntityManager.ShowEntitySuccess += OnShowEntitySuccess; + m_EntityManager.ShowEntityFailure += OnShowEntityFailure; + + if (m_EnableShowEntityUpdateEvent) + { + m_EntityManager.ShowEntityUpdate += OnShowEntityUpdate; + } + + if (m_EnableShowEntityDependencyAssetEvent) + { + m_EntityManager.ShowEntityDependencyAsset += OnShowEntityDependencyAsset; + } + + m_EntityManager.HideEntityComplete += OnHideEntityComplete; + } + + private void Start() + { + BaseComponent baseComponent = GameEntry.GetComponent(); + if (baseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (baseComponent.EditorResourceMode) + { + m_EntityManager.SetResourceManager(baseComponent.EditorResourceHelper); + } + else + { + m_EntityManager.SetResourceManager(GameFrameworkEntry.GetModule()); + } + + m_EntityManager.SetObjectPoolManager(GameFrameworkEntry.GetModule()); + + EntityHelperBase entityHelper = Helper.CreateHelper(m_EntityHelperTypeName, m_CustomEntityHelper); + if (entityHelper == null) + { + Log.Error("Can not create entity helper."); + return; + } + + entityHelper.name = "Entity Helper"; + Transform transform = entityHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_EntityManager.SetEntityHelper(entityHelper); + + if (m_InstanceRoot == null) + { + m_InstanceRoot = new GameObject("Entity Instances").transform; + m_InstanceRoot.SetParent(gameObject.transform); + m_InstanceRoot.localScale = Vector3.one; + } + + for (int i = 0; i < m_EntityGroups.Length; i++) + { + if (!AddEntityGroup(m_EntityGroups[i].Name, m_EntityGroups[i].InstanceAutoReleaseInterval, m_EntityGroups[i].InstanceCapacity, m_EntityGroups[i].InstanceExpireTime, m_EntityGroups[i].InstancePriority)) + { + Log.Warning("Add entity group '{0}' failure.", m_EntityGroups[i].Name); + continue; + } + } + } + + /// + /// 是否存在实体组。 + /// + /// 实体组名称。 + /// 是否存在实体组。 + public bool HasEntityGroup(string entityGroupName) + { + return m_EntityManager.HasEntityGroup(entityGroupName); + } + + /// + /// 获取实体组。 + /// + /// 实体组名称。 + /// 要获取的实体组。 + public IEntityGroup GetEntityGroup(string entityGroupName) + { + return m_EntityManager.GetEntityGroup(entityGroupName); + } + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + public IEntityGroup[] GetAllEntityGroups() + { + return m_EntityManager.GetAllEntityGroups(); + } + + /// + /// 获取所有实体组。 + /// + /// 所有实体组。 + public void GetAllEntityGroups(List results) + { + m_EntityManager.GetAllEntityGroups(results); + } + + /// + /// 增加实体组。 + /// + /// 实体组名称。 + /// 实体实例对象池自动释放可释放对象的间隔秒数。 + /// 实体实例对象池容量。 + /// 实体实例对象池对象过期秒数。 + /// 实体实例对象池的优先级。 + /// 是否增加实体组成功。 + public bool AddEntityGroup(string entityGroupName, float instanceAutoReleaseInterval, int instanceCapacity, float instanceExpireTime, int instancePriority) + { + if (m_EntityManager.HasEntityGroup(entityGroupName)) + { + return false; + } + + EntityGroupHelperBase entityGroupHelper = Helper.CreateHelper(m_EntityGroupHelperTypeName, m_CustomEntityGroupHelper, EntityGroupCount); + if (entityGroupHelper == null) + { + Log.Error("Can not create entity group helper."); + return false; + } + + entityGroupHelper.name = Utility.Text.Format("Entity Group - {0}", entityGroupName); + Transform transform = entityGroupHelper.transform; + transform.SetParent(m_InstanceRoot); + transform.localScale = Vector3.one; + + return m_EntityManager.AddEntityGroup(entityGroupName, instanceAutoReleaseInterval, instanceCapacity, instanceExpireTime, instancePriority, entityGroupHelper); + } + + /// + /// 是否存在实体。 + /// + /// 实体编号。 + /// 是否存在实体。 + public bool HasEntity(int entityId) + { + return m_EntityManager.HasEntity(entityId); + } + + /// + /// 是否存在实体。 + /// + /// 实体资源名称。 + /// 是否存在实体。 + public bool HasEntity(string entityAssetName) + { + return m_EntityManager.HasEntity(entityAssetName); + } + + /// + /// 获取实体。 + /// + /// 实体编号。 + /// 实体。 + public Entity GetEntity(int entityId) + { + return (Entity)m_EntityManager.GetEntity(entityId); + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public Entity GetEntity(string entityAssetName) + { + return (Entity)m_EntityManager.GetEntity(entityAssetName); + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public Entity[] GetEntities(string entityAssetName) + { + IEntity[] entities = m_EntityManager.GetEntities(entityAssetName); + Entity[] entityImpls = new Entity[entities.Length]; + for (int i = 0; i < entities.Length; i++) + { + entityImpls[i] = (Entity)entities[i]; + } + + return entityImpls; + } + + /// + /// 获取实体。 + /// + /// 实体资源名称。 + /// 要获取的实体。 + public void GetEntities(string entityAssetName, List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_EntityManager.GetEntities(entityAssetName, m_InternalEntityResults); + foreach (IEntity entity in m_InternalEntityResults) + { + results.Add((Entity)entity); + } + } + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + public Entity[] GetAllLoadedEntities() + { + IEntity[] entities = m_EntityManager.GetAllLoadedEntities(); + Entity[] entityImpls = new Entity[entities.Length]; + for (int i = 0; i < entities.Length; i++) + { + entityImpls[i] = (Entity)entities[i]; + } + + return entityImpls; + } + + /// + /// 获取所有已加载的实体。 + /// + /// 所有已加载的实体。 + public void GetAllLoadedEntities(List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_EntityManager.GetAllLoadedEntities(m_InternalEntityResults); + foreach (IEntity entity in m_InternalEntityResults) + { + results.Add((Entity)entity); + } + } + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + public int[] GetAllLoadingEntityIds() + { + return m_EntityManager.GetAllLoadingEntityIds(); + } + + /// + /// 获取所有正在加载实体的编号。 + /// + /// 所有正在加载实体的编号。 + public void GetAllLoadingEntityIds(List results) + { + m_EntityManager.GetAllLoadingEntityIds(results); + } + + /// + /// 是否正在加载实体。 + /// + /// 实体编号。 + /// 是否正在加载实体。 + public bool IsLoadingEntity(int entityId) + { + return m_EntityManager.IsLoadingEntity(entityId); + } + + /// + /// 是否是合法的实体。 + /// + /// 实体。 + /// 实体是否合法。 + public bool IsValidEntity(Entity entity) + { + return m_EntityManager.IsValidEntity(entity); + } + + /// + /// 显示实体。 + /// + /// 实体逻辑类型。 + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName) where T : EntityLogic + { + ShowEntity(entityId, typeof(T), entityAssetName, entityGroupName, DefaultPriority, null); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体逻辑类型。 + /// 实体资源名称。 + /// 实体组名称。 + public void ShowEntity(int entityId, Type entityLogicType, string entityAssetName, string entityGroupName) + { + ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, DefaultPriority, null); + } + + /// + /// 显示实体。 + /// + /// 实体逻辑类型。 + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority) where T : EntityLogic + { + ShowEntity(entityId, typeof(T), entityAssetName, entityGroupName, priority, null); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体逻辑类型。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + public void ShowEntity(int entityId, Type entityLogicType, string entityAssetName, string entityGroupName, int priority) + { + ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, priority, null); + } + + /// + /// 显示实体。 + /// + /// 实体逻辑类型。 + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, object userData) where T : EntityLogic + { + ShowEntity(entityId, typeof(T), entityAssetName, entityGroupName, DefaultPriority, userData); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体逻辑类型。 + /// 实体资源名称。 + /// 实体组名称。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, Type entityLogicType, string entityAssetName, string entityGroupName, object userData) + { + ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, DefaultPriority, userData); + } + + /// + /// 显示实体。 + /// + /// 实体逻辑类型。 + /// 实体编号。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, string entityAssetName, string entityGroupName, int priority, object userData) where T : EntityLogic + { + ShowEntity(entityId, typeof(T), entityAssetName, entityGroupName, priority, userData); + } + + /// + /// 显示实体。 + /// + /// 实体编号。 + /// 实体逻辑类型。 + /// 实体资源名称。 + /// 实体组名称。 + /// 加载实体资源的优先级。 + /// 用户自定义数据。 + public void ShowEntity(int entityId, Type entityLogicType, string entityAssetName, string entityGroupName, int priority, object userData) + { + if (entityLogicType == null) + { + Log.Error("Entity type is invalid."); + return; + } + + m_EntityManager.ShowEntity(entityId, entityAssetName, entityGroupName, priority, ShowEntityInfo.Create(entityLogicType, userData)); + } + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + public void HideEntity(int entityId) + { + m_EntityManager.HideEntity(entityId); + } + + /// + /// 隐藏实体。 + /// + /// 实体编号。 + /// 用户自定义数据。 + public void HideEntity(int entityId, object userData) + { + m_EntityManager.HideEntity(entityId, userData); + } + + /// + /// 隐藏实体。 + /// + /// 实体。 + public void HideEntity(Entity entity) + { + m_EntityManager.HideEntity(entity); + } + + /// + /// 隐藏实体。 + /// + /// 实体。 + /// 用户自定义数据。 + public void HideEntity(Entity entity, object userData) + { + m_EntityManager.HideEntity(entity, userData); + } + + /// + /// 隐藏所有已加载的实体。 + /// + public void HideAllLoadedEntities() + { + m_EntityManager.HideAllLoadedEntities(); + } + + /// + /// 隐藏所有已加载的实体。 + /// + /// 用户自定义数据。 + public void HideAllLoadedEntities(object userData) + { + m_EntityManager.HideAllLoadedEntities(userData); + } + + /// + /// 隐藏所有正在加载的实体。 + /// + public void HideAllLoadingEntities() + { + m_EntityManager.HideAllLoadingEntities(); + } + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体的实体编号。 + /// 子实体的父实体。 + public Entity GetParentEntity(int childEntityId) + { + return (Entity)m_EntityManager.GetParentEntity(childEntityId); + } + + /// + /// 获取父实体。 + /// + /// 要获取父实体的子实体。 + /// 子实体的父实体。 + public Entity GetParentEntity(Entity childEntity) + { + return (Entity)m_EntityManager.GetParentEntity(childEntity); + } + + /// + /// 获取子实体数量。 + /// + /// 要获取子实体数量的父实体的实体编号。 + /// 子实体数量。 + public int GetChildEntityCount(int parentEntityId) + { + return m_EntityManager.GetChildEntityCount(parentEntityId); + } + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体的实体编号。 + /// 子实体。 + public Entity GetChildEntity(int parentEntityId) + { + return (Entity)m_EntityManager.GetChildEntity(parentEntityId); + } + + /// + /// 获取子实体。 + /// + /// 要获取子实体的父实体。 + /// 子实体。 + public Entity GetChildEntity(IEntity parentEntity) + { + return (Entity)m_EntityManager.GetChildEntity(parentEntity); + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + public Entity[] GetChildEntities(int parentEntityId) + { + IEntity[] entities = m_EntityManager.GetChildEntities(parentEntityId); + Entity[] entityImpls = new Entity[entities.Length]; + for (int i = 0; i < entities.Length; i++) + { + entityImpls[i] = (Entity)entities[i]; + } + + return entityImpls; + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体的实体编号。 + /// 所有子实体。 + public void GetChildEntities(int parentEntityId, List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_EntityManager.GetChildEntities(parentEntityId, m_InternalEntityResults); + foreach (IEntity entity in m_InternalEntityResults) + { + results.Add((Entity)entity); + } + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + public Entity[] GetChildEntities(Entity parentEntity) + { + IEntity[] entities = m_EntityManager.GetChildEntities(parentEntity); + Entity[] entityImpls = new Entity[entities.Length]; + for (int i = 0; i < entities.Length; i++) + { + entityImpls[i] = (Entity)entities[i]; + } + + return entityImpls; + } + + /// + /// 获取所有子实体。 + /// + /// 要获取所有子实体的父实体。 + /// 所有子实体。 + public void GetChildEntities(IEntity parentEntity, List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_EntityManager.GetChildEntities(parentEntity, m_InternalEntityResults); + foreach (IEntity entity in m_InternalEntityResults) + { + results.Add((Entity)entity); + } + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + public void AttachEntity(int childEntityId, int parentEntityId) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), string.Empty, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + public void AttachEntity(int childEntityId, Entity parentEntity) + { + AttachEntity(GetEntity(childEntityId), parentEntity, string.Empty, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + public void AttachEntity(Entity childEntity, int parentEntityId) + { + AttachEntity(childEntity, GetEntity(parentEntityId), string.Empty, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + public void AttachEntity(Entity childEntity, Entity parentEntity) + { + AttachEntity(childEntity, parentEntity, string.Empty, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(int childEntityId, int parentEntityId, string parentTransformPath) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), parentTransformPath, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(int childEntityId, Entity parentEntity, string parentTransformPath) + { + AttachEntity(GetEntity(childEntityId), parentEntity, parentTransformPath, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(Entity childEntity, int parentEntityId, string parentTransformPath) + { + AttachEntity(childEntity, GetEntity(parentEntityId), parentTransformPath, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(Entity childEntity, Entity parentEntity, string parentTransformPath) + { + AttachEntity(childEntity, parentEntity, parentTransformPath, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(int childEntityId, int parentEntityId, Transform parentTransform) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), parentTransform, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(int childEntityId, Entity parentEntity, Transform parentTransform) + { + AttachEntity(GetEntity(childEntityId), parentEntity, parentTransform, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(Entity childEntity, int parentEntityId, Transform parentTransform) + { + AttachEntity(childEntity, GetEntity(parentEntityId), parentTransform, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + public void AttachEntity(Entity childEntity, Entity parentEntity, Transform parentTransform) + { + AttachEntity(childEntity, parentEntity, parentTransform, null); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, int parentEntityId, object userData) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), string.Empty, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, Entity parentEntity, object userData) + { + AttachEntity(GetEntity(childEntityId), parentEntity, string.Empty, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, int parentEntityId, object userData) + { + AttachEntity(childEntity, GetEntity(parentEntityId), string.Empty, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, Entity parentEntity, object userData) + { + AttachEntity(childEntity, parentEntity, string.Empty, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, int parentEntityId, string parentTransformPath, object userData) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), parentTransformPath, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, Entity parentEntity, string parentTransformPath, object userData) + { + AttachEntity(GetEntity(childEntityId), parentEntity, parentTransformPath, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, int parentEntityId, string parentTransformPath, object userData) + { + AttachEntity(childEntity, GetEntity(parentEntityId), parentTransformPath, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, Entity parentEntity, string parentTransformPath, object userData) + { + if (childEntity == null) + { + Log.Warning("Child entity is invalid."); + return; + } + + if (parentEntity == null) + { + Log.Warning("Parent entity is invalid."); + return; + } + + Transform parentTransform = null; + if (string.IsNullOrEmpty(parentTransformPath)) + { + parentTransform = parentEntity.Logic.CachedTransform; + } + else + { + parentTransform = parentEntity.Logic.CachedTransform.Find(parentTransformPath); + if (parentTransform == null) + { + Log.Warning("Can not find transform path '{0}' from parent entity '{1}'.", parentTransformPath, parentEntity.Logic.Name); + parentTransform = parentEntity.Logic.CachedTransform; + } + } + + AttachEntity(childEntity, parentEntity, parentTransform, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, int parentEntityId, Transform parentTransform, object userData) + { + AttachEntity(GetEntity(childEntityId), GetEntity(parentEntityId), parentTransform, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体的实体编号。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(int childEntityId, Entity parentEntity, Transform parentTransform, object userData) + { + AttachEntity(GetEntity(childEntityId), parentEntity, parentTransform, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体的实体编号。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, int parentEntityId, Transform parentTransform, object userData) + { + AttachEntity(childEntity, GetEntity(parentEntityId), parentTransform, userData); + } + + /// + /// 附加子实体。 + /// + /// 要附加的子实体。 + /// 被附加的父实体。 + /// 相对于被附加父实体的位置。 + /// 用户自定义数据。 + public void AttachEntity(Entity childEntity, Entity parentEntity, Transform parentTransform, object userData) + { + if (childEntity == null) + { + Log.Warning("Child entity is invalid."); + return; + } + + if (parentEntity == null) + { + Log.Warning("Parent entity is invalid."); + return; + } + + if (parentTransform == null) + { + parentTransform = parentEntity.Logic.CachedTransform; + } + + m_EntityManager.AttachEntity(childEntity, parentEntity, AttachEntityInfo.Create(parentTransform, userData)); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + public void DetachEntity(int childEntityId) + { + m_EntityManager.DetachEntity(childEntityId); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体的实体编号。 + /// 用户自定义数据。 + public void DetachEntity(int childEntityId, object userData) + { + m_EntityManager.DetachEntity(childEntityId, userData); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + public void DetachEntity(Entity childEntity) + { + m_EntityManager.DetachEntity(childEntity); + } + + /// + /// 解除子实体。 + /// + /// 要解除的子实体。 + /// 用户自定义数据。 + public void DetachEntity(Entity childEntity, object userData) + { + m_EntityManager.DetachEntity(childEntity, userData); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + public void DetachChildEntities(int parentEntityId) + { + m_EntityManager.DetachChildEntities(parentEntityId); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体的实体编号。 + /// 用户自定义数据。 + public void DetachChildEntities(int parentEntityId, object userData) + { + m_EntityManager.DetachChildEntities(parentEntityId, userData); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + public void DetachChildEntities(Entity parentEntity) + { + m_EntityManager.DetachChildEntities(parentEntity); + } + + /// + /// 解除所有子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + public void DetachChildEntities(Entity parentEntity, object userData) + { + m_EntityManager.DetachChildEntities(parentEntity, userData); + } + + /// + /// 设置实体是否被加锁。 + /// + /// 实体。 + /// 实体是否被加锁。 + public void SetEntityInstanceLocked(Entity entity, bool locked) + { + if (entity == null) + { + Log.Warning("Entity is invalid."); + return; + } + + IEntityGroup entityGroup = entity.EntityGroup; + if (entityGroup == null) + { + Log.Warning("Entity group is invalid."); + return; + } + + entityGroup.SetEntityInstanceLocked(entity.gameObject, locked); + } + + /// + /// 设置实体的优先级。 + /// + /// 实体。 + /// 实体优先级。 + public void SetInstancePriority(Entity entity, int priority) + { + if (entity == null) + { + Log.Warning("Entity is invalid."); + return; + } + + IEntityGroup entityGroup = entity.EntityGroup; + if (entityGroup == null) + { + Log.Warning("Entity group is invalid."); + return; + } + + entityGroup.SetEntityInstancePriority(entity.gameObject, priority); + } + + private void OnShowEntitySuccess(object sender, GameFramework.Entity.ShowEntitySuccessEventArgs e) + { + m_EventComponent.Fire(this, ShowEntitySuccessEventArgs.Create(e)); + } + + private void OnShowEntityFailure(object sender, GameFramework.Entity.ShowEntityFailureEventArgs e) + { + Log.Warning("Show entity failure, entity id '{0}', asset name '{1}', entity group name '{2}', error message '{3}'.", e.EntityId, e.EntityAssetName, e.EntityGroupName, e.ErrorMessage); + m_EventComponent.Fire(this, ShowEntityFailureEventArgs.Create(e)); + } + + private void OnShowEntityUpdate(object sender, GameFramework.Entity.ShowEntityUpdateEventArgs e) + { + m_EventComponent.Fire(this, ShowEntityUpdateEventArgs.Create(e)); + } + + private void OnShowEntityDependencyAsset(object sender, GameFramework.Entity.ShowEntityDependencyAssetEventArgs e) + { + m_EventComponent.Fire(this, ShowEntityDependencyAssetEventArgs.Create(e)); + } + + private void OnHideEntityComplete(object sender, GameFramework.Entity.HideEntityCompleteEventArgs e) + { + m_EventComponent.Fire(this, HideEntityCompleteEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.cs.meta new file mode 100644 index 0000000..63e55aa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58aa63e99dabf9c4fb61a9ec4ac4d8ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityGroupHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityGroupHelperBase.cs new file mode 100644 index 0000000..d54d61b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityGroupHelperBase.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Entity; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 实体组辅助器基类。 + /// + public abstract class EntityGroupHelperBase : MonoBehaviour, IEntityGroupHelper + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityGroupHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityGroupHelperBase.cs.meta new file mode 100644 index 0000000..d85d80d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityGroupHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb8122bd1a1ff7d4cb0a9806d5b3f065 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityHelperBase.cs new file mode 100644 index 0000000..191e46c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityHelperBase.cs @@ -0,0 +1,41 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Entity; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 实体辅助器基类。 + /// + public abstract class EntityHelperBase : MonoBehaviour, IEntityHelper + { + /// + /// 实例化实体。 + /// + /// 要实例化的实体资源。 + /// 实例化后的实体。 + public abstract object InstantiateEntity(object entityAsset); + + /// + /// 创建实体。 + /// + /// 实体实例。 + /// 实体所属的实体组。 + /// 用户自定义数据。 + /// 实体。 + public abstract IEntity CreateEntity(object entityInstance, IEntityGroup entityGroup, object userData); + + /// + /// 释放实体。 + /// + /// 要释放的实体资源。 + /// 要释放的实体实例。 + public abstract void ReleaseEntity(object entityAsset, object entityInstance); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityHelperBase.cs.meta new file mode 100644 index 0000000..fea74fd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8992f89de70519047ba31e6383445cca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityLogic.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityLogic.cs new file mode 100644 index 0000000..aa9f2db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityLogic.cs @@ -0,0 +1,202 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 实体逻辑基类。 + /// + public abstract class EntityLogic : MonoBehaviour + { + private bool m_Available = false; + private bool m_Visible = false; + private Entity m_Entity = null; + private Transform m_CachedTransform = null; + private int m_OriginalLayer = 0; + private Transform m_OriginalTransform = null; + + /// + /// 获取实体。 + /// + public Entity Entity + { + get + { + return m_Entity; + } + } + + /// + /// 获取或设置实体名称。 + /// + public string Name + { + get + { + return gameObject.name; + } + set + { + gameObject.name = value; + } + } + + /// + /// 获取实体是否可用。 + /// + public bool Available + { + get + { + return m_Available; + } + } + + /// + /// 获取或设置实体是否可见。 + /// + public bool Visible + { + get + { + return m_Available && m_Visible; + } + set + { + if (!m_Available) + { + Log.Warning("Entity '{0}' is not available.", Name); + return; + } + + if (m_Visible == value) + { + return; + } + + m_Visible = value; + InternalSetVisible(value); + } + } + + /// + /// 获取已缓存的 Transform。 + /// + public Transform CachedTransform + { + get + { + return m_CachedTransform; + } + } + + /// + /// 实体初始化。 + /// + /// 用户自定义数据。 + protected internal virtual void OnInit(object userData) + { + if (m_CachedTransform == null) + { + m_CachedTransform = transform; + } + + m_Entity = GetComponent(); + m_OriginalLayer = gameObject.layer; + m_OriginalTransform = CachedTransform.parent; + } + + /// + /// 实体回收。 + /// + protected internal virtual void OnRecycle() + { + } + + /// + /// 实体显示。 + /// + /// 用户自定义数据。 + protected internal virtual void OnShow(object userData) + { + m_Available = true; + Visible = true; + } + + /// + /// 实体隐藏。 + /// + /// 是否是关闭实体管理器时触发。 + /// 用户自定义数据。 + protected internal virtual void OnHide(bool isShutdown, object userData) + { + gameObject.SetLayerRecursively(m_OriginalLayer); + Visible = false; + m_Available = false; + } + + /// + /// 实体附加子实体。 + /// + /// 附加的子实体。 + /// 被附加父实体的位置。 + /// 用户自定义数据。 + protected internal virtual void OnAttached(EntityLogic childEntity, Transform parentTransform, object userData) + { + } + + /// + /// 实体解除子实体。 + /// + /// 解除的子实体。 + /// 用户自定义数据。 + protected internal virtual void OnDetached(EntityLogic childEntity, object userData) + { + } + + /// + /// 实体附加子实体。 + /// + /// 被附加的父实体。 + /// 被附加父实体的位置。 + /// 用户自定义数据。 + protected internal virtual void OnAttachTo(EntityLogic parentEntity, Transform parentTransform, object userData) + { + CachedTransform.SetParent(parentTransform); + } + + /// + /// 实体解除子实体。 + /// + /// 被解除的父实体。 + /// 用户自定义数据。 + protected internal virtual void OnDetachFrom(EntityLogic parentEntity, object userData) + { + CachedTransform.SetParent(m_OriginalTransform); + } + + /// + /// 实体轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + protected internal virtual void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 设置实体的可见性。 + /// + /// 实体的可见性。 + protected virtual void InternalSetVisible(bool visible) + { + gameObject.SetActive(visible); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityLogic.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityLogic.cs.meta new file mode 100644 index 0000000..82446b8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/EntityLogic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 699dd149c0a53234e8f76e6d6c1b5545 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/HideEntityCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/HideEntityCompleteEventArgs.cs new file mode 100644 index 0000000..2244fa5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/HideEntityCompleteEventArgs.cs @@ -0,0 +1,108 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Entity; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 隐藏实体完成事件。 + /// + public sealed class HideEntityCompleteEventArgs : GameEventArgs + { + /// + /// 隐藏实体完成事件编号。 + /// + public static readonly int EventId = typeof(HideEntityCompleteEventArgs).GetHashCode(); + + /// + /// 初始化隐藏实体完成事件的新实例。 + /// + public HideEntityCompleteEventArgs() + { + EntityId = 0; + EntityAssetName = null; + EntityGroup = null; + UserData = null; + } + + /// + /// 获取隐藏实体完成事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取实体编号。 + /// + public int EntityId + { + get; + private set; + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get; + private set; + } + + /// + /// 获取实体所属的实体组。 + /// + public IEntityGroup EntityGroup + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建隐藏实体完成事件。 + /// + /// 内部事件。 + /// 创建的隐藏实体完成事件。 + public static HideEntityCompleteEventArgs Create(GameFramework.Entity.HideEntityCompleteEventArgs e) + { + HideEntityCompleteEventArgs hideEntityCompleteEventArgs = ReferencePool.Acquire(); + hideEntityCompleteEventArgs.EntityId = e.EntityId; + hideEntityCompleteEventArgs.EntityAssetName = e.EntityAssetName; + hideEntityCompleteEventArgs.EntityGroup = e.EntityGroup; + hideEntityCompleteEventArgs.UserData = e.UserData; + return hideEntityCompleteEventArgs; + } + + /// + /// 清理隐藏实体完成事件。 + /// + public override void Clear() + { + EntityId = 0; + EntityAssetName = null; + EntityGroup = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/HideEntityCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/HideEntityCompleteEventArgs.cs.meta new file mode 100644 index 0000000..96661d2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/HideEntityCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 852f69476ad9a2e4cb44c564a250aff2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs new file mode 100644 index 0000000..5b4a334 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs @@ -0,0 +1,157 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using System; + +namespace UnityGameFramework.Runtime +{ + /// + /// 显示实体时加载依赖资源事件。 + /// + public sealed class ShowEntityDependencyAssetEventArgs : GameEventArgs + { + /// + /// 显示实体时加载依赖资源事件编号。 + /// + public static readonly int EventId = typeof(ShowEntityDependencyAssetEventArgs).GetHashCode(); + + /// + /// 初始化显示实体时加载依赖资源事件的新实例。 + /// + public ShowEntityDependencyAssetEventArgs() + { + EntityId = 0; + EntityLogicType = null; + EntityAssetName = null; + EntityGroupName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取显示实体时加载依赖资源事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取实体编号。 + /// + public int EntityId + { + get; + private set; + } + + /// + /// 获取实体逻辑类型。 + /// + public Type EntityLogicType + { + get; + private set; + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get; + private set; + } + + /// + /// 获取实体组名称。 + /// + public string EntityGroupName + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建显示实体时加载依赖资源事件。 + /// + /// 内部事件。 + /// 创建的显示实体时加载依赖资源事件。 + public static ShowEntityDependencyAssetEventArgs Create(GameFramework.Entity.ShowEntityDependencyAssetEventArgs e) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)e.UserData; + ShowEntityDependencyAssetEventArgs showEntityDependencyAssetEventArgs = ReferencePool.Acquire(); + showEntityDependencyAssetEventArgs.EntityId = e.EntityId; + showEntityDependencyAssetEventArgs.EntityLogicType = showEntityInfo.EntityLogicType; + showEntityDependencyAssetEventArgs.EntityAssetName = e.EntityAssetName; + showEntityDependencyAssetEventArgs.EntityGroupName = e.EntityGroupName; + showEntityDependencyAssetEventArgs.DependencyAssetName = e.DependencyAssetName; + showEntityDependencyAssetEventArgs.LoadedCount = e.LoadedCount; + showEntityDependencyAssetEventArgs.TotalCount = e.TotalCount; + showEntityDependencyAssetEventArgs.UserData = showEntityInfo.UserData; + return showEntityDependencyAssetEventArgs; + } + + /// + /// 清理显示实体时加载依赖资源事件。 + /// + public override void Clear() + { + EntityId = 0; + EntityLogicType = null; + EntityAssetName = null; + EntityGroupName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..e63ed01 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cef77d19116ea6f4aaa8b77116df65c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityFailureEventArgs.cs new file mode 100644 index 0000000..78b0188 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityFailureEventArgs.cs @@ -0,0 +1,134 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using System; + +namespace UnityGameFramework.Runtime +{ + /// + /// 显示实体失败事件。 + /// + public sealed class ShowEntityFailureEventArgs : GameEventArgs + { + /// + /// 显示实体失败事件编号。 + /// + public static readonly int EventId = typeof(ShowEntityFailureEventArgs).GetHashCode(); + + /// + /// 初始化显示实体失败事件的新实例。 + /// + public ShowEntityFailureEventArgs() + { + EntityId = 0; + EntityLogicType = null; + EntityAssetName = null; + EntityGroupName = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取显示实体失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取实体编号。 + /// + public int EntityId + { + get; + private set; + } + + /// + /// 获取实体逻辑类型。 + /// + public Type EntityLogicType + { + get; + private set; + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get; + private set; + } + + /// + /// 获取实体组名称。 + /// + public string EntityGroupName + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建显示实体失败事件。 + /// + /// 内部事件。 + /// 创建的显示实体失败事件。 + public static ShowEntityFailureEventArgs Create(GameFramework.Entity.ShowEntityFailureEventArgs e) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)e.UserData; + ShowEntityFailureEventArgs showEntityFailureEventArgs = ReferencePool.Acquire(); + showEntityFailureEventArgs.EntityId = e.EntityId; + showEntityFailureEventArgs.EntityLogicType = showEntityInfo.EntityLogicType; + showEntityFailureEventArgs.EntityAssetName = e.EntityAssetName; + showEntityFailureEventArgs.EntityGroupName = e.EntityGroupName; + showEntityFailureEventArgs.ErrorMessage = e.ErrorMessage; + showEntityFailureEventArgs.UserData = showEntityInfo.UserData; + ReferencePool.Release(showEntityInfo); + return showEntityFailureEventArgs; + } + + /// + /// 清理显示实体失败事件。 + /// + public override void Clear() + { + EntityId = 0; + EntityLogicType = null; + EntityAssetName = null; + EntityGroupName = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityFailureEventArgs.cs.meta new file mode 100644 index 0000000..a8e08db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7188888f5121ad44bfaba20e4ed7ca9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityInfo.cs new file mode 100644 index 0000000..0960049 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityInfo.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; + +namespace UnityGameFramework.Runtime +{ + internal sealed class ShowEntityInfo : IReference + { + private Type m_EntityLogicType; + private object m_UserData; + + public ShowEntityInfo() + { + m_EntityLogicType = null; + m_UserData = null; + } + + public Type EntityLogicType + { + get + { + return m_EntityLogicType; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + + public static ShowEntityInfo Create(Type entityLogicType, object userData) + { + ShowEntityInfo showEntityInfo = ReferencePool.Acquire(); + showEntityInfo.m_EntityLogicType = entityLogicType; + showEntityInfo.m_UserData = userData; + return showEntityInfo; + } + + public void Clear() + { + m_EntityLogicType = null; + m_UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityInfo.cs.meta new file mode 100644 index 0000000..26b3a5b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5535dde509ba87b42912084f30591779 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntitySuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntitySuccessEventArgs.cs new file mode 100644 index 0000000..f202229 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntitySuccessEventArgs.cs @@ -0,0 +1,110 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using System; + +namespace UnityGameFramework.Runtime +{ + /// + /// 显示实体成功事件。 + /// + public sealed class ShowEntitySuccessEventArgs : GameEventArgs + { + /// + /// 显示实体成功事件编号。 + /// + public static readonly int EventId = typeof(ShowEntitySuccessEventArgs).GetHashCode(); + + /// + /// 初始化显示实体成功事件的新实例。 + /// + public ShowEntitySuccessEventArgs() + { + EntityLogicType = null; + Entity = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取显示实体成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取实体逻辑类型。 + /// + public Type EntityLogicType + { + get; + private set; + } + + /// + /// 获取显示成功的实体。 + /// + public Entity Entity + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建显示实体成功事件。 + /// + /// 内部事件。 + /// 创建的显示实体成功事件。 + public static ShowEntitySuccessEventArgs Create(GameFramework.Entity.ShowEntitySuccessEventArgs e) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)e.UserData; + ShowEntitySuccessEventArgs showEntitySuccessEventArgs = ReferencePool.Acquire(); + showEntitySuccessEventArgs.EntityLogicType = showEntityInfo.EntityLogicType; + showEntitySuccessEventArgs.Entity = (Entity)e.Entity; + showEntitySuccessEventArgs.Duration = e.Duration; + showEntitySuccessEventArgs.UserData = showEntityInfo.UserData; + ReferencePool.Release(showEntityInfo); + return showEntitySuccessEventArgs; + } + + /// + /// 清理显示实体成功事件。 + /// + public override void Clear() + { + EntityLogicType = null; + Entity = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntitySuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntitySuccessEventArgs.cs.meta new file mode 100644 index 0000000..8057f5f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntitySuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9786630f2f7760f4da147cd8173e9b18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityUpdateEventArgs.cs new file mode 100644 index 0000000..c1aef33 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityUpdateEventArgs.cs @@ -0,0 +1,133 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using System; + +namespace UnityGameFramework.Runtime +{ + /// + /// 显示实体更新事件。 + /// + public sealed class ShowEntityUpdateEventArgs : GameEventArgs + { + /// + /// 显示实体更新事件编号。 + /// + public static readonly int EventId = typeof(ShowEntityUpdateEventArgs).GetHashCode(); + + /// + /// 初始化显示实体更新事件的新实例。 + /// + public ShowEntityUpdateEventArgs() + { + EntityId = 0; + EntityLogicType = null; + EntityAssetName = null; + EntityGroupName = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取显示实体更新事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取实体编号。 + /// + public int EntityId + { + get; + private set; + } + + /// + /// 获取实体逻辑类型。 + /// + public Type EntityLogicType + { + get; + private set; + } + + /// + /// 获取实体资源名称。 + /// + public string EntityAssetName + { + get; + private set; + } + + /// + /// 获取实体组名称。 + /// + public string EntityGroupName + { + get; + private set; + } + + /// + /// 获取显示实体进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建显示实体更新事件。 + /// + /// 内部事件。 + /// 创建的显示实体更新事件。 + public static ShowEntityUpdateEventArgs Create(GameFramework.Entity.ShowEntityUpdateEventArgs e) + { + ShowEntityInfo showEntityInfo = (ShowEntityInfo)e.UserData; + ShowEntityUpdateEventArgs showEntityUpdateEventArgs = ReferencePool.Acquire(); + showEntityUpdateEventArgs.EntityId = e.EntityId; + showEntityUpdateEventArgs.EntityLogicType = showEntityInfo.EntityLogicType; + showEntityUpdateEventArgs.EntityAssetName = e.EntityAssetName; + showEntityUpdateEventArgs.EntityGroupName = e.EntityGroupName; + showEntityUpdateEventArgs.Progress = e.Progress; + showEntityUpdateEventArgs.UserData = showEntityInfo.UserData; + return showEntityUpdateEventArgs; + } + + /// + /// 清理显示实体更新事件。 + /// + public override void Clear() + { + EntityId = 0; + EntityLogicType = null; + EntityAssetName = null; + EntityGroupName = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityUpdateEventArgs.cs.meta new file mode 100644 index 0000000..8d2313a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Entity/ShowEntityUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8fb90ce75efc136468379f5728401d0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event.meta new file mode 100644 index 0000000..f7bb531 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6a1049d8ab8f5f147831166d2e3a8db7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event/EventComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event/EventComponent.cs new file mode 100644 index 0000000..ed391cf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event/EventComponent.cs @@ -0,0 +1,135 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 事件组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Event")] + public sealed class EventComponent : GameFrameworkComponent + { + private IEventManager m_EventManager = null; + + /// + /// 获取事件处理函数的数量。 + /// + public int EventHandlerCount + { + get + { + return m_EventManager.EventHandlerCount; + } + } + + /// + /// 获取事件数量。 + /// + public int EventCount + { + get + { + return m_EventManager.EventCount; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_EventManager = GameFrameworkEntry.GetModule(); + if (m_EventManager == null) + { + Log.Fatal("Event manager is invalid."); + return; + } + } + + private void Start() + { + } + + /// + /// 获取事件处理函数的数量。 + /// + /// 事件类型编号。 + /// 事件处理函数的数量。 + public int Count(int id) + { + return m_EventManager.Count(id); + } + + /// + /// 检查是否存在事件处理函数。 + /// + /// 事件类型编号。 + /// 要检查的事件处理函数。 + /// 是否存在事件处理函数。 + public bool Check(int id, EventHandler handler) + { + return m_EventManager.Check(id, handler); + } + + /// + /// 订阅事件处理回调函数。 + /// + /// 事件类型编号。 + /// 要订阅的事件处理回调函数。 + public void Subscribe(int id, EventHandler handler) + { + m_EventManager.Subscribe(id, handler); + } + + /// + /// 取消订阅事件处理回调函数。 + /// + /// 事件类型编号。 + /// 要取消订阅的事件处理回调函数。 + public void Unsubscribe(int id, EventHandler handler) + { + m_EventManager.Unsubscribe(id, handler); + } + + /// + /// 设置默认事件处理函数。 + /// + /// 要设置的默认事件处理函数。 + public void SetDefaultHandler(EventHandler handler) + { + m_EventManager.SetDefaultHandler(handler); + } + + /// + /// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。 + /// + /// 事件发送者。 + /// 事件内容。 + public void Fire(object sender, GameEventArgs e) + { + m_EventManager.Fire(sender, e); + } + + /// + /// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。 + /// + /// 事件发送者。 + /// 事件内容。 + public void FireNow(object sender, GameEventArgs e) + { + m_EventManager.FireNow(sender, e); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event/EventComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event/EventComponent.cs.meta new file mode 100644 index 0000000..f83dff9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Event/EventComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7daf8320a3d04046b4bbd7c47307914 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem.meta new file mode 100644 index 0000000..d242d82 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 080a8216f14ee5047b7fc9d20c8baf37 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/AndroidFileSystemStream.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/AndroidFileSystemStream.cs new file mode 100644 index 0000000..05cf30e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/AndroidFileSystemStream.cs @@ -0,0 +1,293 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.FileSystem; +using System; +using System.IO; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 安卓文件系统流。 + /// + public sealed class AndroidFileSystemStream : FileSystemStream + { + private static readonly string SplitFlag = "!/assets/"; + private static readonly int SplitFlagLength = SplitFlag.Length; + private static readonly AndroidJavaObject s_AssetManager = null; + private static readonly IntPtr s_InternalReadMethodId = IntPtr.Zero; + private static readonly jvalue[] s_InternalReadArgs = null; + + private readonly AndroidJavaObject m_FileStream; + private readonly IntPtr m_FileStreamRawObject; + + static AndroidFileSystemStream() + { + AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + if (unityPlayer == null) + { + throw new GameFrameworkException("Unity player is invalid."); + } + + AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity"); + if (currentActivity == null) + { + throw new GameFrameworkException("Current activity is invalid."); + } + + AndroidJavaObject assetManager = currentActivity.Call("getAssets"); + if (assetManager == null) + { + throw new GameFrameworkException("Asset manager is invalid."); + } + + s_AssetManager = assetManager; + + IntPtr inputStreamClassPtr = AndroidJNI.FindClass("java/io/InputStream"); + s_InternalReadMethodId = AndroidJNIHelper.GetMethodID(inputStreamClassPtr, "read", "([BII)I"); + s_InternalReadArgs = new jvalue[3]; + + AndroidJNI.DeleteLocalRef(inputStreamClassPtr); + currentActivity.Dispose(); + unityPlayer.Dispose(); + } + + /// + /// 初始化安卓文件系统流的新实例。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 是否创建新的文件系统流。 + public AndroidFileSystemStream(string fullPath, FileSystemAccess access, bool createNew) + { + if (string.IsNullOrEmpty(fullPath)) + { + throw new GameFrameworkException("Full path is invalid."); + } + + if (access != FileSystemAccess.Read) + { + throw new GameFrameworkException(Utility.Text.Format("'{0}' is not supported in AndroidFileSystemStream.", access)); + } + + if (createNew) + { + throw new GameFrameworkException("Create new is not supported in AndroidFileSystemStream."); + } + + int position = fullPath.LastIndexOf(SplitFlag, StringComparison.Ordinal); + if (position < 0) + { + throw new GameFrameworkException("Can not find split flag in full path."); + } + + string fileName = fullPath.Substring(position + SplitFlagLength); + m_FileStream = InternalOpen(fileName); + if (m_FileStream == null) + { + throw new GameFrameworkException(Utility.Text.Format("Open file '{0}' from Android asset manager failure.", fullPath)); + } + + m_FileStreamRawObject = m_FileStream.GetRawObject(); + } + + /// + /// 获取或设置文件系统流位置。 + /// + public override long Position + { + get + { + throw new GameFrameworkException("Get position is not supported in AndroidFileSystemStream."); + } + set + { + Seek(value, SeekOrigin.Begin); + } + } + + /// + /// 获取文件系统流长度。 + /// + public override long Length + { + get + { + return InternalAvailable(); + } + } + + /// + /// 设置文件系统流长度。 + /// + /// 要设置的文件系统流的长度。 + public override void SetLength(long length) + { + throw new GameFrameworkException("SetLength is not supported in AndroidFileSystemStream."); + } + + /// + /// 定位文件系统流位置。 + /// + /// 要定位的文件系统流位置的偏移。 + /// 要定位的文件系统流位置的方式。 + public override void Seek(long offset, SeekOrigin origin) + { + if (origin == SeekOrigin.End) + { + Seek(Length + offset, SeekOrigin.Begin); + return; + } + + if (origin == SeekOrigin.Begin) + { + InternalReset(); + } + + while (offset > 0) + { + long skip = InternalSkip(offset); + if (skip < 0) + { + return; + } + + offset -= skip; + } + } + + /// + /// 从文件系统流中读取一个字节。 + /// + /// 读取的字节,若已经到达文件结尾,则返回 -1。 + public override int ReadByte() + { + return InternalRead(); + } + + /// + /// 从文件系统流中读取二进制流。 + /// + /// 存储读取文件内容的二进制流。 + /// 存储读取文件内容的二进制流的起始位置。 + /// 存储读取文件内容的二进制流的长度。 + /// 实际读取了多少字节。 + public override int Read(byte[] buffer, int startIndex, int length) + { + byte[] result = null; + int bytesRead = InternalRead(length, out result); + Array.Copy(result, 0, buffer, startIndex, bytesRead); + return bytesRead; + } + + /// + /// 向文件系统流中写入一个字节。 + /// + /// 要写入的字节。 + public override void WriteByte(byte value) + { + throw new GameFrameworkException("WriteByte is not supported in AndroidFileSystemStream."); + } + + /// + /// 向文件系统流中写入二进制流。 + /// + /// 存储写入文件内容的二进制流。 + /// 存储写入文件内容的二进制流的起始位置。 + /// 存储写入文件内容的二进制流的长度。 + public override void Write(byte[] buffer, int startIndex, int length) + { + throw new GameFrameworkException("Write is not supported in AndroidFileSystemStream."); + } + + /// + /// 将文件系统流立刻更新到存储介质中。 + /// + public override void Flush() + { + throw new GameFrameworkException("Flush is not supported in AndroidFileSystemStream."); + } + + /// + /// 关闭文件系统流。 + /// + public override void Close() + { + InternalClose(); + m_FileStream.Dispose(); + } + + private AndroidJavaObject InternalOpen(string fileName) + { + return s_AssetManager.Call("open", fileName); + } + + private int InternalAvailable() + { + return m_FileStream.Call("available"); + } + + private void InternalClose() + { + m_FileStream.Call("close"); + } + + private int InternalRead() + { + return m_FileStream.Call("read"); + } + + private int InternalRead(int length, out byte[] result) + { +#if UNITY_2019_2_OR_NEWER +#pragma warning disable CS0618 +#endif + IntPtr resultPtr = AndroidJNI.NewByteArray(length); +#if UNITY_2019_2_OR_NEWER +#pragma warning restore CS0618 +#endif + int offset = 0; + int bytesLeft = length; + while (bytesLeft > 0) + { + s_InternalReadArgs[0] = new jvalue() { l = resultPtr }; + s_InternalReadArgs[1] = new jvalue() { i = offset }; + s_InternalReadArgs[2] = new jvalue() { i = bytesLeft }; + int bytesRead = AndroidJNI.CallIntMethod(m_FileStreamRawObject, s_InternalReadMethodId, s_InternalReadArgs); + if (bytesRead <= 0) + { + break; + } + + offset += bytesRead; + bytesLeft -= bytesRead; + } + +#if UNITY_2019_2_OR_NEWER +#pragma warning disable CS0618 +#endif + result = AndroidJNI.FromByteArray(resultPtr); +#if UNITY_2019_2_OR_NEWER +#pragma warning restore CS0618 +#endif + AndroidJNI.DeleteLocalRef(resultPtr); + return offset; + } + + private void InternalReset() + { + m_FileStream.Call("reset"); + } + + private long InternalSkip(long offset) + { + return m_FileStream.Call("skip", offset); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/AndroidFileSystemStream.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/AndroidFileSystemStream.cs.meta new file mode 100644 index 0000000..a44dc07 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/AndroidFileSystemStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e91d57307e5c7674c855d299cfb466b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/DefaultFileSystemHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/DefaultFileSystemHelper.cs new file mode 100644 index 0000000..1704e2a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/DefaultFileSystemHelper.cs @@ -0,0 +1,39 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; +using System; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认文件系统辅助器。 + /// + public class DefaultFileSystemHelper : FileSystemHelperBase + { + private const string AndroidFileSystemPrefixString = "jar:"; + + /// + /// 创建文件系统流。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 是否创建新的文件系统流。 + /// 创建的文件系统流。 + public override FileSystemStream CreateFileSystemStream(string fullPath, FileSystemAccess access, bool createNew) + { + if (fullPath.StartsWith(AndroidFileSystemPrefixString, StringComparison.Ordinal)) + { + return new AndroidFileSystemStream(fullPath, access, createNew); + } + else + { + return new CommonFileSystemStream(fullPath, access, createNew); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/DefaultFileSystemHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/DefaultFileSystemHelper.cs.meta new file mode 100644 index 0000000..37f3edf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/DefaultFileSystemHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab61553d44f971447856311f2f7aef44 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemComponent.cs new file mode 100644 index 0000000..8e8407b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemComponent.cs @@ -0,0 +1,146 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.FileSystem; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 文件系统件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/File System")] + public sealed class FileSystemComponent : GameFrameworkComponent + { + private IFileSystemManager m_FileSystemManager = null; + + [SerializeField] + private string m_FileSystemHelperTypeName = "UnityGameFramework.Runtime.DefaultFileSystemHelper"; + + [SerializeField] + private FileSystemHelperBase m_CustomFileSystemHelper = null; + + /// + /// 获取文件系统数量。 + /// + public int Count + { + get + { + return m_FileSystemManager.Count; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_FileSystemManager = GameFrameworkEntry.GetModule(); + if (m_FileSystemManager == null) + { + Log.Fatal("File system manager is invalid."); + return; + } + + FileSystemHelperBase fileSystemHelper = Helper.CreateHelper(m_FileSystemHelperTypeName, m_CustomFileSystemHelper); + if (fileSystemHelper == null) + { + Log.Error("Can not create fileSystem helper."); + return; + } + + fileSystemHelper.name = "FileSystem Helper"; + Transform transform = fileSystemHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_FileSystemManager.SetFileSystemHelper(fileSystemHelper); + } + + private void Start() + { + } + + /// + /// 检查是否存在文件系统。 + /// + /// 要检查的文件系统的完整路径。 + /// 是否存在文件系统。 + public bool HasFileSystem(string fullPath) + { + return m_FileSystemManager.HasFileSystem(fullPath); + } + + /// + /// 获取文件系统。 + /// + /// 要获取的文件系统的完整路径。 + /// 获取的文件系统。 + public IFileSystem GetFileSystem(string fullPath) + { + return m_FileSystemManager.GetFileSystem(fullPath); + } + + /// + /// 创建文件系统。 + /// + /// 要创建的文件系统的完整路径。 + /// 要创建的文件系统的访问方式。 + /// 要创建的文件系统的最大文件数量。 + /// 要创建的文件系统的最大块数据数量。 + /// 创建的文件系统。 + public IFileSystem CreateFileSystem(string fullPath, FileSystemAccess access, int maxFileCount, int maxBlockCount) + { + return m_FileSystemManager.CreateFileSystem(fullPath, access, maxFileCount, maxBlockCount); + } + + /// + /// 加载文件系统。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 加载的文件系统。 + public IFileSystem LoadFileSystem(string fullPath, FileSystemAccess access) + { + return m_FileSystemManager.LoadFileSystem(fullPath, access); + } + + /// + /// 销毁文件系统。 + /// + /// 要销毁的文件系统。 + /// 是否删除文件系统对应的物理文件。 + public void DestroyFileSystem(IFileSystem fileSystem, bool deletePhysicalFile) + { + m_FileSystemManager.DestroyFileSystem(fileSystem, deletePhysicalFile); + } + + /// + /// 获取所有文件系统集合。 + /// + /// 获取的所有文件系统集合。 + public IFileSystem[] GetAllFileSystems() + { + return m_FileSystemManager.GetAllFileSystems(); + } + + /// + /// 获取所有文件系统集合。 + /// + /// 获取的所有文件系统集合。 + public void GetAllFileSystems(List results) + { + m_FileSystemManager.GetAllFileSystems(results); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemComponent.cs.meta new file mode 100644 index 0000000..a714d8f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc49d78dad061a2418e134fc48856bc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemHelperBase.cs new file mode 100644 index 0000000..7c623b5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemHelperBase.cs @@ -0,0 +1,27 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 文件系统辅助器基类。 + /// + public abstract class FileSystemHelperBase : MonoBehaviour, IFileSystemHelper + { + /// + /// 创建文件系统流。 + /// + /// 要加载的文件系统的完整路径。 + /// 要加载的文件系统的访问方式。 + /// 是否创建新的文件系统流。 + /// 创建的文件系统流。 + public abstract FileSystemStream CreateFileSystemStream(string fullPath, FileSystemAccess access, bool createNew); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemHelperBase.cs.meta new file mode 100644 index 0000000..62d330d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/FileSystem/FileSystemHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40934320d6b918548891a29641dc0a20 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm.meta new file mode 100644 index 0000000..c47f972 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 82c3050d1857b3e47be8bb68926c81cf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm/FsmComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm/FsmComponent.cs new file mode 100644 index 0000000..4dbf996 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm/FsmComponent.cs @@ -0,0 +1,269 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Fsm; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 有限状态机组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/FSM")] + public sealed class FsmComponent : GameFrameworkComponent + { + private IFsmManager m_FsmManager = null; + + /// + /// 获取有限状态机数量。 + /// + public int Count + { + get + { + return m_FsmManager.Count; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_FsmManager = GameFrameworkEntry.GetModule(); + if (m_FsmManager == null) + { + Log.Fatal("FSM manager is invalid."); + return; + } + } + + private void Start() + { + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + public bool HasFsm() where T : class + { + return m_FsmManager.HasFsm(); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + public bool HasFsm(Type ownerType) + { + return m_FsmManager.HasFsm(ownerType); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + public bool HasFsm(string name) where T : class + { + return m_FsmManager.HasFsm(name); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + public bool HasFsm(Type ownerType, string name) + { + return m_FsmManager.HasFsm(ownerType, name); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + public IFsm GetFsm() where T : class + { + return m_FsmManager.GetFsm(); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + public FsmBase GetFsm(Type ownerType) + { + return m_FsmManager.GetFsm(ownerType); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + public IFsm GetFsm(string name) where T : class + { + return m_FsmManager.GetFsm(name); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + public FsmBase GetFsm(Type ownerType, string name) + { + return m_FsmManager.GetFsm(ownerType, name); + } + + /// + /// 获取所有有限状态机。 + /// + public FsmBase[] GetAllFsms() + { + return m_FsmManager.GetAllFsms(); + } + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + public void GetAllFsms(List results) + { + m_FsmManager.GetAllFsms(results); + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(T owner, params FsmState[] states) where T : class + { + return m_FsmManager.CreateFsm(owner, states); + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(string name, T owner, params FsmState[] states) where T : class + { + return m_FsmManager.CreateFsm(name, owner, states); + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(T owner, List> states) where T : class + { + return m_FsmManager.CreateFsm(owner, states); + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(string name, T owner, List> states) where T : class + { + return m_FsmManager.CreateFsm(name, owner, states); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm() where T : class + { + return m_FsmManager.DestroyFsm(); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(Type ownerType) + { + return m_FsmManager.DestroyFsm(ownerType); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(string name) where T : class + { + return m_FsmManager.DestroyFsm(name); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(Type ownerType, string name) + { + return m_FsmManager.DestroyFsm(ownerType, name); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(IFsm fsm) where T : class + { + return m_FsmManager.DestroyFsm(fsm); + } + + /// + /// 销毁有限状态机。 + /// + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(FsmBase fsm) + { + return m_FsmManager.DestroyFsm(fsm); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm/FsmComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm/FsmComponent.cs.meta new file mode 100644 index 0000000..adbbf83 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Fsm/FsmComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac872c3ce4121bb46a74927b35780534 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/GameFramework.prefab b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/GameFramework.prefab new file mode 100644 index 0000000..5d2dbbc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/GameFramework.prefab @@ -0,0 +1,1190 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &105264 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 447378} + - component: {fileID: 11472694} + m_Layer: 0 + m_Name: FSM + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &447378 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 105264} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11472694 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 105264} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ac872c3ce4121bb46a74927b35780534, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &108464 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 432002} + - component: {fileID: 11497722} + m_Layer: 0 + m_Name: Resource + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &432002 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 108464} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11497722 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 108464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7eff66e40586ec14d8a301d416f17f1e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ResourceMode: 1 + m_ReadWritePathType: 0 + m_MinUnloadUnusedAssetsInterval: 60 + m_MaxUnloadUnusedAssetsInterval: 300 + m_AssetAutoReleaseInterval: 60 + m_AssetCapacity: 64 + m_AssetExpireTime: 60 + m_AssetPriority: 10000 + m_ResourceAutoReleaseInterval: 60 + m_ResourceCapacity: 16 + m_ResourceExpireTime: 60 + m_ResourcePriority: 20000 + m_UpdatePrefixUri: + m_GenerateReadWriteVersionListLength: 1048576 + m_UpdateRetryCount: 3 + m_InstanceRoot: {fileID: 0} + m_ResourceHelperTypeName: UnityGameFramework.Runtime.DefaultResourceHelper + m_CustomResourceHelper: {fileID: 0} + m_LoadResourceAgentHelperTypeName: UnityGameFramework.Runtime.DefaultLoadResourceAgentHelper + m_CustomLoadResourceAgentHelper: {fileID: 0} + m_LoadResourceAgentHelperCount: 3 + HotUpdateScripts: + OtherHotUpdateScripts: +--- !u!1 &109252 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 472962} + - component: {fileID: 11461470} + m_Layer: 0 + m_Name: Localization + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &472962 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 109252} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11461470 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 109252} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 706e6317a59f61044b2805be79f6b284, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableLoadDictionaryUpdateEvent: 0 + m_EnableLoadDictionaryDependencyAssetEvent: 0 + m_LocalizationHelperTypeName: UnityGameFramework.Runtime.DefaultLocalizationHelper + m_CustomLocalizationHelper: {fileID: 0} + m_CachedBytesSize: 0 +--- !u!1 &109548 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 472238} + - component: {fileID: 11420954} + m_Layer: 0 + m_Name: Download + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &472238 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 109548} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11420954 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 109548} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9259de0854ba2624aa59aca15c6af063, type: 3} + m_Name: + m_EditorClassIdentifier: + m_InstanceRoot: {fileID: 0} + m_DownloadAgentHelperTypeName: UnityGameFramework.Runtime.UnityWebRequestDownloadAgentHelper + m_CustomDownloadAgentHelper: {fileID: 0} + m_DownloadAgentHelperCount: 3 + m_Timeout: 30 + m_FlushSize: 1048576 +--- !u!1 &110832 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 449550} + - component: {fileID: 11494652} + m_Layer: 0 + m_Name: Entity + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &449550 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 110832} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11494652 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 110832} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 58aa63e99dabf9c4fb61a9ec4ac4d8ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableShowEntityUpdateEvent: 0 + m_EnableShowEntityDependencyAssetEvent: 0 + m_InstanceRoot: {fileID: 0} + m_EntityHelperTypeName: UnityGameFramework.Runtime.DefaultEntityHelper + m_CustomEntityHelper: {fileID: 0} + m_EntityGroupHelperTypeName: UnityGameFramework.Runtime.DefaultEntityGroupHelper + m_CustomEntityGroupHelper: {fileID: 0} + m_EntityGroups: [] +--- !u!1 &116470 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 433714} + - component: {fileID: 11499388} + - component: {fileID: 11463816} + m_Layer: 0 + m_Name: GameFramework + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &433714 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 116470} + serializedVersion: 2 + 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: 436184} + - {fileID: 455962} + - {fileID: 465000} + - {fileID: 404872} + - {fileID: 472238} + - {fileID: 449550} + - {fileID: 401796} + - {fileID: 429090} + - {fileID: 447378} + - {fileID: 472962} + - {fileID: 486648} + - {fileID: 431700} + - {fileID: 407686} + - {fileID: 461836} + - {fileID: 432002} + - {fileID: 449996} + - {fileID: 490662} + - {fileID: 463618} + - {fileID: 430602} + - {fileID: 450964} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11499388 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 116470} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f98acd7d3bd2bf54dadf9644f60e5cb9, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EditorResourceMode: 1 + m_EditorLanguage: 0 + m_TextHelperTypeName: + m_VersionHelperTypeName: + m_LogHelperTypeName: + m_CompressionHelperTypeName: + m_JsonHelperTypeName: + m_FrameRate: 30 + m_GameSpeed: 1 + m_RunInBackground: 1 + m_NeverSleep: 1 +--- !u!114 &11463816 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 116470} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c26ec20b78ec32048bfb6c0ff875d8cd, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableCachedAssets: 1 + m_LoadAssetCountPerFrame: 1 + m_MinLoadAssetRandomDelaySeconds: 0 + m_MaxLoadAssetRandomDelaySeconds: 0 +--- !u!1 &118246 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 429090} + - component: {fileID: 11417814} + m_Layer: 0 + m_Name: File System + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &429090 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 118246} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11417814 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 118246} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fc49d78dad061a2418e134fc48856bc9, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FileSystemHelperTypeName: UnityGameFramework.Runtime.DefaultFileSystemHelper + m_CustomFileSystemHelper: {fileID: 0} +--- !u!1 &119488 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 404872} + - component: {fileID: 11402440} + m_Layer: 0 + m_Name: Debugger + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &404872 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 119488} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11402440 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 119488} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f05eaceeebe870a4595e51f998ed518b, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Skin: {fileID: 0} + m_ActiveWindow: 0 + m_ShowFullWindow: 0 + m_ConsoleWindow: + m_LockScroll: 1 + m_MaxLine: 100 + m_InfoFilter: 1 + m_WarningFilter: 1 + m_ErrorFilter: 1 + m_FatalFilter: 1 + m_InfoColor: + serializedVersion: 2 + rgba: 4294967295 + m_WarningColor: + serializedVersion: 2 + rgba: 4278512639 + m_ErrorColor: + serializedVersion: 2 + rgba: 4278190335 + m_FatalColor: + serializedVersion: 2 + rgba: 4281545650 +--- !u!1 &126534 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 450964} + - component: {fileID: 11447244} + m_Layer: 0 + m_Name: Web Request + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &450964 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 126534} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11447244 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 126534} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 02988897571ac8b49a59c1a50037bd88, type: 3} + m_Name: + m_EditorClassIdentifier: + m_InstanceRoot: {fileID: 0} + m_WebRequestAgentHelperTypeName: UnityGameFramework.Runtime.UnityWebRequestAgentHelper + m_CustomWebRequestAgentHelper: {fileID: 0} + m_WebRequestAgentHelperCount: 1 + m_Timeout: 30 +--- !u!1 &132194 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 490662} + - component: {fileID: 11459312} + m_Layer: 0 + m_Name: Setting + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &490662 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 132194} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11459312 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 132194} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3c6e05d8d843cd94bb9aa026ed5dc517, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SettingHelperTypeName: UnityGameFramework.Runtime.DefaultSettingHelper + m_CustomSettingHelper: {fileID: 0} +--- !u!1 &137260 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 436184} + - component: {fileID: 11485274} + m_Layer: 0 + m_Name: Config + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &436184 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 137260} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11485274 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 137260} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3e847b2b3e22e9b4792ca7ea6e1714c6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableLoadConfigUpdateEvent: 0 + m_EnableLoadConfigDependencyAssetEvent: 0 + m_ConfigHelperTypeName: UnityGameFramework.Runtime.DefaultConfigHelper + m_CustomConfigHelper: {fileID: 0} + m_CachedBytesSize: 0 +--- !u!1 &139170 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 407686} + - component: {fileID: 11405216} + m_Layer: 0 + m_Name: Procedure + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &407686 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 139170} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11405216 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 139170} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 959bca2b68d03954897f38b1dbb00303, type: 3} + m_Name: + m_EditorClassIdentifier: + m_AvailableProcedureTypeNames: [] + m_EntranceProcedureTypeName: +--- !u!1 &140694 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 463618} + - component: {fileID: 11413340} + m_Layer: 0 + m_Name: Sound + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &463618 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 140694} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11413340 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 140694} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ed5533de69c4e5a4dabc7c23fce1fa98, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnablePlaySoundUpdateEvent: 0 + m_EnablePlaySoundDependencyAssetEvent: 0 + m_InstanceRoot: {fileID: 0} + m_AudioMixer: {fileID: 0} + m_SoundHelperTypeName: UnityGameFramework.Runtime.DefaultSoundHelper + m_CustomSoundHelper: {fileID: 0} + m_SoundGroupHelperTypeName: UnityGameFramework.Runtime.DefaultSoundGroupHelper + m_CustomSoundGroupHelper: {fileID: 0} + m_SoundAgentHelperTypeName: UnityGameFramework.Runtime.DefaultSoundAgentHelper + m_CustomSoundAgentHelper: {fileID: 0} + m_SoundGroups: [] +--- !u!1 &151938 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 401796} + - component: {fileID: 11457798} + m_Layer: 0 + m_Name: Event + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &401796 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 151938} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11457798 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 151938} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d7daf8320a3d04046b4bbd7c47307914, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &159784 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 431700} + - component: {fileID: 11402158} + m_Layer: 0 + m_Name: Object Pool + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &431700 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 159784} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11402158 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 159784} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1e28a727443c86c40aeb42ff20e0a343, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &167768 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 430602} + - component: {fileID: 11454530} + m_Layer: 0 + m_Name: UI + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &430602 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167768} + serializedVersion: 2 + 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: 2378499584788586608} + m_Father: {fileID: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11454530 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167768} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4a1ef15380caaed42b55022cadc93649, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableOpenUIFormSuccessEvent: 1 + m_EnableOpenUIFormFailureEvent: 1 + m_EnableOpenUIFormUpdateEvent: 0 + m_EnableOpenUIFormDependencyAssetEvent: 0 + m_EnableCloseUIFormCompleteEvent: 1 + m_InstanceAutoReleaseInterval: 60 + m_InstanceCapacity: 16 + m_InstanceExpireTime: 60 + m_InstancePriority: 0 + m_InstanceRoot: {fileID: 0} + m_UIFormHelperTypeName: UnityGameFramework.Runtime.DefaultUIFormHelper + m_CustomUIFormHelper: {fileID: 0} + m_UIGroupHelperTypeName: UnityGameFramework.Runtime.DefaultUIGroupHelper + m_CustomUIGroupHelper: {fileID: 0} + m_UIGroups: [] +--- !u!1 &176370 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 486648} + - component: {fileID: 11431030} + m_Layer: 0 + m_Name: Network + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &486648 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 176370} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11431030 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 176370} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7afc859893311c34a8d8c2c426ab192d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &178960 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 455962} + - component: {fileID: 11447582} + m_Layer: 0 + m_Name: Data Node + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &455962 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 178960} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11447582 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 178960} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 67038fd9feefc894aa31ae3869a45b72, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &179612 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 465000} + - component: {fileID: 11451924} + m_Layer: 0 + m_Name: Data Table + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &465000 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 179612} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11451924 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 179612} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 54066418ab853614483ea44b531049f0, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableLoadDataTableUpdateEvent: 0 + m_EnableLoadDataTableDependencyAssetEvent: 0 + m_DataTableHelperTypeName: UnityGameFramework.Runtime.DefaultDataTableHelper + m_CustomDataTableHelper: {fileID: 0} + m_CachedBytesSize: 0 +--- !u!1 &180508 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 449996} + - component: {fileID: 11418144} + m_Layer: 0 + m_Name: Scene + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &449996 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 180508} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11418144 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 180508} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b6242b052eb207b40b22e8fe77a315ba, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableLoadSceneUpdateEvent: 1 + m_EnableLoadSceneDependencyAssetEvent: 1 +--- !u!1 &189908 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 461836} + - component: {fileID: 11461162} + m_Layer: 0 + m_Name: Reference Pool + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &461836 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 189908} + serializedVersion: 2 + 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: 433714} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11461162 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 189908} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ae4d40d7e878bc498492dc9c410d071, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EnableStrictCheck: 0 +--- !u!1 &6165926768569987664 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2378499584788586608} + - component: {fileID: 1899184134033788353} + - component: {fileID: 7534603576128669706} + - component: {fileID: 1017202406165695093} + m_Layer: 5 + m_Name: UI Form Instances + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2378499584788586608 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165926768569987664} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 430602} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!223 &1899184134033788353 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165926768569987664} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 1 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 0 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &7534603576128669706 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165926768569987664} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 1080, y: 1920} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!114 &1017202406165695093 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6165926768569987664} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/GameFramework.prefab.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/GameFramework.prefab.meta new file mode 100644 index 0000000..2361c78 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/GameFramework.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: adb3eb1c35fcff14f89fba7b05c9d71c +NativeFormatImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization.meta new file mode 100644 index 0000000..972188f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 53c22c721e664fb45b53af7ab274c8af +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/DefaultLocalizationHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/DefaultLocalizationHelper.cs new file mode 100644 index 0000000..b6e3e22 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/DefaultLocalizationHelper.cs @@ -0,0 +1,238 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Localization; +using System; +using System.IO; +using System.Text; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认本地化辅助器。 + /// + public class DefaultLocalizationHelper : LocalizationHelperBase + { + private static readonly string[] ColumnSplitSeparator = new string[] { "\t" }; + private static readonly string BytesAssetExtension = ".bytes"; + private const int ColumnCount = 4; + + private ResourceComponent m_ResourceComponent = null; + + /// + /// 获取系统语言。 + /// + public override Language SystemLanguage + { + get + { + switch (Application.systemLanguage) + { + case UnityEngine.SystemLanguage.Afrikaans: return Language.Afrikaans; + case UnityEngine.SystemLanguage.Arabic: return Language.Arabic; + case UnityEngine.SystemLanguage.Basque: return Language.Basque; + case UnityEngine.SystemLanguage.Belarusian: return Language.Belarusian; + case UnityEngine.SystemLanguage.Bulgarian: return Language.Bulgarian; + case UnityEngine.SystemLanguage.Catalan: return Language.Catalan; + case UnityEngine.SystemLanguage.Chinese: return Language.ChineseSimplified; + case UnityEngine.SystemLanguage.ChineseSimplified: return Language.ChineseSimplified; + case UnityEngine.SystemLanguage.ChineseTraditional: return Language.ChineseTraditional; + case UnityEngine.SystemLanguage.Czech: return Language.Czech; + case UnityEngine.SystemLanguage.Danish: return Language.Danish; + case UnityEngine.SystemLanguage.Dutch: return Language.Dutch; + case UnityEngine.SystemLanguage.English: return Language.English; + case UnityEngine.SystemLanguage.Estonian: return Language.Estonian; + case UnityEngine.SystemLanguage.Faroese: return Language.Faroese; + case UnityEngine.SystemLanguage.Finnish: return Language.Finnish; + case UnityEngine.SystemLanguage.French: return Language.French; + case UnityEngine.SystemLanguage.German: return Language.German; + case UnityEngine.SystemLanguage.Greek: return Language.Greek; + case UnityEngine.SystemLanguage.Hebrew: return Language.Hebrew; + case UnityEngine.SystemLanguage.Hungarian: return Language.Hungarian; + case UnityEngine.SystemLanguage.Icelandic: return Language.Icelandic; + case UnityEngine.SystemLanguage.Indonesian: return Language.Indonesian; + case UnityEngine.SystemLanguage.Italian: return Language.Italian; + case UnityEngine.SystemLanguage.Japanese: return Language.Japanese; + case UnityEngine.SystemLanguage.Korean: return Language.Korean; + case UnityEngine.SystemLanguage.Latvian: return Language.Latvian; + case UnityEngine.SystemLanguage.Lithuanian: return Language.Lithuanian; + case UnityEngine.SystemLanguage.Norwegian: return Language.Norwegian; + case UnityEngine.SystemLanguage.Polish: return Language.Polish; + case UnityEngine.SystemLanguage.Portuguese: return Language.PortuguesePortugal; + case UnityEngine.SystemLanguage.Romanian: return Language.Romanian; + case UnityEngine.SystemLanguage.Russian: return Language.Russian; + case UnityEngine.SystemLanguage.SerboCroatian: return Language.SerboCroatian; + case UnityEngine.SystemLanguage.Slovak: return Language.Slovak; + case UnityEngine.SystemLanguage.Slovenian: return Language.Slovenian; + case UnityEngine.SystemLanguage.Spanish: return Language.Spanish; + case UnityEngine.SystemLanguage.Swedish: return Language.Swedish; + case UnityEngine.SystemLanguage.Thai: return Language.Thai; + case UnityEngine.SystemLanguage.Turkish: return Language.Turkish; + case UnityEngine.SystemLanguage.Ukrainian: return Language.Ukrainian; + case UnityEngine.SystemLanguage.Unknown: return Language.Unspecified; + case UnityEngine.SystemLanguage.Vietnamese: return Language.Vietnamese; + default: return Language.Unspecified; + } + } + } + + /// + /// 读取字典。 + /// + /// 本地化管理器。 + /// 字典资源名称。 + /// 字典资源。 + /// 用户自定义数据。 + /// 是否读取字典成功。 + public override bool ReadData(ILocalizationManager localizationManager, string dictionaryAssetName, object dictionaryAsset, object userData) + { + TextAsset dictionaryTextAsset = dictionaryAsset as TextAsset; + if (dictionaryTextAsset != null) + { + if (dictionaryAssetName.EndsWith(BytesAssetExtension, StringComparison.Ordinal)) + { + return localizationManager.ParseData(dictionaryTextAsset.bytes, userData); + } + else + { + return localizationManager.ParseData(dictionaryTextAsset.text, userData); + } + } + + Log.Warning("Dictionary asset '{0}' is invalid.", dictionaryAssetName); + return false; + } + + /// + /// 读取字典。 + /// + /// 本地化管理器。 + /// 字典资源名称。 + /// 字典二进制流。 + /// 字典二进制流的起始位置。 + /// 字典二进制流的长度。 + /// 用户自定义数据。 + /// 是否读取字典成功。 + public override bool ReadData(ILocalizationManager localizationManager, string dictionaryAssetName, byte[] dictionaryBytes, int startIndex, int length, object userData) + { + if (dictionaryAssetName.EndsWith(BytesAssetExtension, StringComparison.Ordinal)) + { + return localizationManager.ParseData(dictionaryBytes, startIndex, length, userData); + } + else + { + return localizationManager.ParseData(Utility.Converter.GetString(dictionaryBytes, startIndex, length), userData); + } + } + + /// + /// 解析字典。 + /// + /// 本地化管理器。 + /// 要解析的字典字符串。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public override bool ParseData(ILocalizationManager localizationManager, string dictionaryString, object userData) + { + try + { + int position = 0; + string dictionaryLineString = null; + while ((dictionaryLineString = dictionaryString.ReadLine(ref position)) != null) + { + if (dictionaryLineString[0] == '#') + { + continue; + } + + string[] splitedLine = dictionaryLineString.Split(ColumnSplitSeparator, StringSplitOptions.None); + if (splitedLine.Length != ColumnCount) + { + Log.Warning("Can not parse dictionary line string '{0}' which column count is invalid.", dictionaryLineString); + return false; + } + + string dictionaryKey = splitedLine[1]; + string dictionaryValue = splitedLine[3]; + if (!localizationManager.AddRawString(dictionaryKey, dictionaryValue)) + { + Log.Warning("Can not add raw string with dictionary key '{0}' which may be invalid or duplicate.", dictionaryKey); + return false; + } + } + + return true; + } + catch (Exception exception) + { + Log.Warning("Can not parse dictionary string with exception '{0}'.", exception); + return false; + } + } + + /// + /// 解析字典。 + /// + /// 本地化管理器。 + /// 要解析的字典二进制流。 + /// 字典二进制流的起始位置。 + /// 字典二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public override bool ParseData(ILocalizationManager localizationManager, byte[] dictionaryBytes, int startIndex, int length, object userData) + { + try + { + using (MemoryStream memoryStream = new MemoryStream(dictionaryBytes, startIndex, length, false)) + { + using (BinaryReader binaryReader = new BinaryReader(memoryStream, Encoding.UTF8)) + { + while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) + { + string dictionaryKey = binaryReader.ReadString(); + string dictionaryValue = binaryReader.ReadString(); + if (!localizationManager.AddRawString(dictionaryKey, dictionaryValue)) + { + Log.Warning("Can not add raw string with dictionary key '{0}' which may be invalid or duplicate.", dictionaryKey); + return false; + } + } + } + } + + return true; + } + catch (Exception exception) + { + Log.Warning("Can not parse dictionary bytes with exception '{0}'.", exception); + return false; + } + } + + /// + /// 释放字典资源。 + /// + /// 本地化管理器。 + /// 要释放的字典资源。 + public override void ReleaseDataAsset(ILocalizationManager localizationManager, object dictionaryAsset) + { + m_ResourceComponent.UnloadAsset(dictionaryAsset); + } + + private void Start() + { + m_ResourceComponent = GameEntry.GetComponent(); + if (m_ResourceComponent == null) + { + Log.Fatal("Resource component is invalid."); + return; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/DefaultLocalizationHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/DefaultLocalizationHelper.cs.meta new file mode 100644 index 0000000..86e3ed7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/DefaultLocalizationHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57465d541030d834b9d764c79af94e2e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryDependencyAssetEventArgs.cs new file mode 100644 index 0000000..3d3ab19 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryDependencyAssetEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载字典时加载依赖资源事件。 + /// + public sealed class LoadDictionaryDependencyAssetEventArgs : GameEventArgs + { + /// + /// 加载字典时加载依赖资源事件编号。 + /// + public static readonly int EventId = typeof(LoadDictionaryDependencyAssetEventArgs).GetHashCode(); + + /// + /// 初始化加载字典时加载依赖资源事件的新实例。 + /// + public LoadDictionaryDependencyAssetEventArgs() + { + DictionaryAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取加载字典时加载依赖资源事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取字典资源名称。 + /// + public string DictionaryAssetName + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载字典时加载依赖资源事件。 + /// + /// 内部事件。 + /// 创建的加载字典时加载依赖资源事件。 + public static LoadDictionaryDependencyAssetEventArgs Create(ReadDataDependencyAssetEventArgs e) + { + LoadDictionaryDependencyAssetEventArgs loadDictionaryDependencyAssetEventArgs = ReferencePool.Acquire(); + loadDictionaryDependencyAssetEventArgs.DictionaryAssetName = e.DataAssetName; + loadDictionaryDependencyAssetEventArgs.DependencyAssetName = e.DependencyAssetName; + loadDictionaryDependencyAssetEventArgs.LoadedCount = e.LoadedCount; + loadDictionaryDependencyAssetEventArgs.TotalCount = e.TotalCount; + loadDictionaryDependencyAssetEventArgs.UserData = e.UserData; + return loadDictionaryDependencyAssetEventArgs; + } + + /// + /// 清理加载字典时加载依赖资源事件。 + /// + public override void Clear() + { + DictionaryAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..d392e63 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b3481fe69ce20a49ad4735ec0d2b9dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryFailureEventArgs.cs new file mode 100644 index 0000000..ed8415e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryFailureEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载字典失败事件。 + /// + public sealed class LoadDictionaryFailureEventArgs : GameEventArgs + { + /// + /// 加载字典失败事件编号。 + /// + public static readonly int EventId = typeof(LoadDictionaryFailureEventArgs).GetHashCode(); + + /// + /// 初始化加载字典失败事件的新实例。 + /// + public LoadDictionaryFailureEventArgs() + { + DictionaryAssetName = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取加载字典失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取字典资源名称。 + /// + public string DictionaryAssetName + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载字典失败事件。 + /// + /// 内部事件。 + /// 创建的加载字典失败事件。 + public static LoadDictionaryFailureEventArgs Create(ReadDataFailureEventArgs e) + { + LoadDictionaryFailureEventArgs loadDictionaryFailureEventArgs = ReferencePool.Acquire(); + loadDictionaryFailureEventArgs.DictionaryAssetName = e.DataAssetName; + loadDictionaryFailureEventArgs.ErrorMessage = e.ErrorMessage; + loadDictionaryFailureEventArgs.UserData = e.UserData; + return loadDictionaryFailureEventArgs; + } + + /// + /// 清理加载字典失败事件。 + /// + public override void Clear() + { + DictionaryAssetName = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryFailureEventArgs.cs.meta new file mode 100644 index 0000000..c91b52e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82e68c5abc85cb346b4dd03c73bb8c10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionarySuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionarySuccessEventArgs.cs new file mode 100644 index 0000000..cfd7153 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionarySuccessEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载字典成功事件。 + /// + public sealed class LoadDictionarySuccessEventArgs : GameEventArgs + { + /// + /// 加载字典成功事件编号。 + /// + public static readonly int EventId = typeof(LoadDictionarySuccessEventArgs).GetHashCode(); + + /// + /// 初始化加载字典成功事件的新实例。 + /// + public LoadDictionarySuccessEventArgs() + { + DictionaryAssetName = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取加载字典成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取字典资源名称。 + /// + public string DictionaryAssetName + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载字典成功事件。 + /// + /// 内部事件。 + /// 创建的加载字典成功事件。 + public static LoadDictionarySuccessEventArgs Create(ReadDataSuccessEventArgs e) + { + LoadDictionarySuccessEventArgs loadDictionarySuccessEventArgs = ReferencePool.Acquire(); + loadDictionarySuccessEventArgs.DictionaryAssetName = e.DataAssetName; + loadDictionarySuccessEventArgs.Duration = e.Duration; + loadDictionarySuccessEventArgs.UserData = e.UserData; + return loadDictionarySuccessEventArgs; + } + + /// + /// 清理加载字典成功事件。 + /// + public override void Clear() + { + DictionaryAssetName = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionarySuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionarySuccessEventArgs.cs.meta new file mode 100644 index 0000000..ee1df06 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionarySuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21fad28624e6eca4e86242e3fe512359 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryUpdateEventArgs.cs new file mode 100644 index 0000000..115d1be --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryUpdateEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载字典更新事件。 + /// + public sealed class LoadDictionaryUpdateEventArgs : GameEventArgs + { + /// + /// 加载字典更新事件编号。 + /// + public static readonly int EventId = typeof(LoadDictionaryUpdateEventArgs).GetHashCode(); + + /// + /// 初始化加载字典更新事件的新实例。 + /// + public LoadDictionaryUpdateEventArgs() + { + DictionaryAssetName = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取加载字典更新事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取字典资源名称。 + /// + public string DictionaryAssetName + { + get; + private set; + } + + /// + /// 获取加载字典进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载字典更新事件。 + /// + /// 内部事件。 + /// 创建的加载字典更新事件。 + public static LoadDictionaryUpdateEventArgs Create(ReadDataUpdateEventArgs e) + { + LoadDictionaryUpdateEventArgs loadDictionaryUpdateEventArgs = ReferencePool.Acquire(); + loadDictionaryUpdateEventArgs.DictionaryAssetName = e.DataAssetName; + loadDictionaryUpdateEventArgs.Progress = e.Progress; + loadDictionaryUpdateEventArgs.UserData = e.UserData; + return loadDictionaryUpdateEventArgs; + } + + /// + /// 清理加载字典更新事件。 + /// + public override void Clear() + { + DictionaryAssetName = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryUpdateEventArgs.cs.meta new file mode 100644 index 0000000..df04e44 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LoadDictionaryUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 067358629da8fc440b396eea65bb6434 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationComponent.cs new file mode 100644 index 0000000..02e7a4b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationComponent.cs @@ -0,0 +1,789 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Localization; +using GameFramework.Resource; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 本地化组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Localization")] + public sealed class LocalizationComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + + private ILocalizationManager m_LocalizationManager = null; + private EventComponent m_EventComponent = null; + + [SerializeField] + private bool m_EnableLoadDictionaryUpdateEvent = false; + + [SerializeField] + private bool m_EnableLoadDictionaryDependencyAssetEvent = false; + + [SerializeField] + private string m_LocalizationHelperTypeName = "UnityGameFramework.Runtime.DefaultLocalizationHelper"; + + [SerializeField] + private LocalizationHelperBase m_CustomLocalizationHelper = null; + + [SerializeField] + private int m_CachedBytesSize = 0; + + /// + /// 获取或设置本地化语言。 + /// + public Language Language + { + get + { + return m_LocalizationManager.Language; + } + set + { + m_LocalizationManager.Language = value; + } + } + + /// + /// 获取系统语言。 + /// + public Language SystemLanguage + { + get + { + return m_LocalizationManager.SystemLanguage; + } + } + + /// + /// 获取字典数量。 + /// + public int DictionaryCount + { + get + { + return m_LocalizationManager.DictionaryCount; + } + } + + /// + /// 获取缓冲二进制流的大小。 + /// + public int CachedBytesSize + { + get + { + return m_LocalizationManager.CachedBytesSize; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_LocalizationManager = GameFrameworkEntry.GetModule(); + if (m_LocalizationManager == null) + { + Log.Fatal("Localization manager is invalid."); + return; + } + + m_LocalizationManager.ReadDataSuccess += OnReadDataSuccess; + m_LocalizationManager.ReadDataFailure += OnReadDataFailure; + + if (m_EnableLoadDictionaryUpdateEvent) + { + m_LocalizationManager.ReadDataUpdate += OnReadDataUpdate; + } + + if (m_EnableLoadDictionaryDependencyAssetEvent) + { + m_LocalizationManager.ReadDataDependencyAsset += OnReadDataDependencyAsset; + } + } + + private void Start() + { + BaseComponent baseComponent = GameEntry.GetComponent(); + if (baseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (baseComponent.EditorResourceMode) + { + m_LocalizationManager.SetResourceManager(baseComponent.EditorResourceHelper); + } + else + { + m_LocalizationManager.SetResourceManager(GameFrameworkEntry.GetModule()); + } + + LocalizationHelperBase localizationHelper = Helper.CreateHelper(m_LocalizationHelperTypeName, m_CustomLocalizationHelper); + if (localizationHelper == null) + { + Log.Error("Can not create localization helper."); + return; + } + + localizationHelper.name = "Localization Helper"; + Transform transform = localizationHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_LocalizationManager.SetDataProviderHelper(localizationHelper); + m_LocalizationManager.SetLocalizationHelper(localizationHelper); + m_LocalizationManager.Language = baseComponent.EditorResourceMode && baseComponent.EditorLanguage != Language.Unspecified ? baseComponent.EditorLanguage : m_LocalizationManager.SystemLanguage; + if (m_CachedBytesSize > 0) + { + EnsureCachedBytesSize(m_CachedBytesSize); + } + } + + /// + /// 确保二进制流缓存分配足够大小的内存并缓存。 + /// + /// 要确保二进制流缓存分配内存的大小。 + public void EnsureCachedBytesSize(int ensureSize) + { + m_LocalizationManager.EnsureCachedBytesSize(ensureSize); + } + + /// + /// 释放缓存的二进制流。 + /// + public void FreeCachedBytes() + { + m_LocalizationManager.FreeCachedBytes(); + } + + /// + /// 读取字典。 + /// + /// 字典资源名称。 + public void ReadData(string dictionaryAssetName) + { + m_LocalizationManager.ReadData(dictionaryAssetName); + } + + /// + /// 读取字典。 + /// + /// 字典资源名称。 + /// 加载字典资源的优先级。 + public void ReadData(string dictionaryAssetName, int priority) + { + m_LocalizationManager.ReadData(dictionaryAssetName, priority); + } + + /// + /// 读取字典。 + /// + /// 字典资源名称。 + /// 用户自定义数据。 + public void ReadData(string dictionaryAssetName, object userData) + { + m_LocalizationManager.ReadData(dictionaryAssetName, userData); + } + + /// + /// 读取字典。 + /// + /// 字典资源名称。 + /// 加载字典资源的优先级。 + /// 用户自定义数据。 + public void ReadData(string dictionaryAssetName, int priority, object userData) + { + m_LocalizationManager.ReadData(dictionaryAssetName, priority, userData); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典字符串。 + /// 是否解析字典成功。 + public bool ParseData(string dictionaryString) + { + return m_LocalizationManager.ParseData(dictionaryString); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典字符串。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public bool ParseData(string dictionaryString, object userData) + { + return m_LocalizationManager.ParseData(dictionaryString, userData); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典二进制流。 + /// 是否解析字典成功。 + public bool ParseData(byte[] dictionaryBytes) + { + return m_LocalizationManager.ParseData(dictionaryBytes); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典二进制流。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public bool ParseData(byte[] dictionaryBytes, object userData) + { + return m_LocalizationManager.ParseData(dictionaryBytes, userData); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典二进制流。 + /// 字典二进制流的起始位置。 + /// 字典二进制流的长度。 + /// 是否解析字典成功。 + public bool ParseData(byte[] dictionaryBytes, int startIndex, int length) + { + return m_LocalizationManager.ParseData(dictionaryBytes, startIndex, length); + } + + /// + /// 解析字典。 + /// + /// 要解析的字典二进制流。 + /// 字典二进制流的起始位置。 + /// 字典二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public bool ParseData(byte[] dictionaryBytes, int startIndex, int length, object userData) + { + return m_LocalizationManager.ParseData(dictionaryBytes, startIndex, length, userData); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典主键。 + /// 要获取的字典内容字符串。 + public string GetString(string key) + { + return m_LocalizationManager.GetString(key); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数的类型。 + /// 字典主键。 + /// 字典参数。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T arg) + { + return m_LocalizationManager.GetString(key, arg); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2) + { + return m_LocalizationManager.GetString(key, arg1, arg2); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典参数 15 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 字典参数 15。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + + /// + /// 根据字典主键获取字典内容字符串。 + /// + /// 字典参数 1 的类型。 + /// 字典参数 2 的类型。 + /// 字典参数 3 的类型。 + /// 字典参数 4 的类型。 + /// 字典参数 5 的类型。 + /// 字典参数 6 的类型。 + /// 字典参数 7 的类型。 + /// 字典参数 8 的类型。 + /// 字典参数 9 的类型。 + /// 字典参数 10 的类型。 + /// 字典参数 11 的类型。 + /// 字典参数 12 的类型。 + /// 字典参数 13 的类型。 + /// 字典参数 14 的类型。 + /// 字典参数 15 的类型。 + /// 字典参数 16 的类型。 + /// 字典主键。 + /// 字典参数 1。 + /// 字典参数 2。 + /// 字典参数 3。 + /// 字典参数 4。 + /// 字典参数 5。 + /// 字典参数 6。 + /// 字典参数 7。 + /// 字典参数 8。 + /// 字典参数 9。 + /// 字典参数 10。 + /// 字典参数 11。 + /// 字典参数 12。 + /// 字典参数 13。 + /// 字典参数 14。 + /// 字典参数 15。 + /// 字典参数 16。 + /// 要获取的字典内容字符串。 + public string GetString(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + return m_LocalizationManager.GetString(key, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + + /// + /// 是否存在字典。 + /// + /// 字典主键。 + /// 是否存在字典。 + public bool HasRawString(string key) + { + return m_LocalizationManager.HasRawString(key); + } + + /// + /// 根据字典主键获取字典值。 + /// + /// 字典主键。 + /// 字典值。 + public string GetRawString(string key) + { + return m_LocalizationManager.GetRawString(key); + } + + /// + /// 移除字典。 + /// + /// 字典主键。 + /// 是否移除字典成功。 + public bool RemoveRawString(string key) + { + return m_LocalizationManager.RemoveRawString(key); + } + + /// + /// 清空所有字典。 + /// + public void RemoveAllRawStrings() + { + m_LocalizationManager.RemoveAllRawStrings(); + } + + private void OnReadDataSuccess(object sender, ReadDataSuccessEventArgs e) + { + m_EventComponent.Fire(this, LoadDictionarySuccessEventArgs.Create(e)); + } + + private void OnReadDataFailure(object sender, ReadDataFailureEventArgs e) + { + Log.Warning("Load dictionary failure, asset name '{0}', error message '{1}'.", e.DataAssetName, e.ErrorMessage); + m_EventComponent.Fire(this, LoadDictionaryFailureEventArgs.Create(e)); + } + + private void OnReadDataUpdate(object sender, ReadDataUpdateEventArgs e) + { + m_EventComponent.Fire(this, LoadDictionaryUpdateEventArgs.Create(e)); + } + + private void OnReadDataDependencyAsset(object sender, ReadDataDependencyAssetEventArgs e) + { + m_EventComponent.Fire(this, LoadDictionaryDependencyAssetEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationComponent.cs.meta new file mode 100644 index 0000000..4a6e097 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 706e6317a59f61044b2805be79f6b284 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationHelperBase.cs new file mode 100644 index 0000000..65f6839 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationHelperBase.cs @@ -0,0 +1,76 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Localization; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 本地化辅助器基类。 + /// + public abstract class LocalizationHelperBase : MonoBehaviour, IDataProviderHelper, ILocalizationHelper + { + /// + /// 获取系统语言。 + /// + public abstract Language SystemLanguage + { + get; + } + + /// + /// 读取字典。 + /// + /// 本地化管理器。 + /// 字典资源名称。 + /// 字典资源。 + /// 用户自定义数据。 + /// 是否读取字典成功。 + public abstract bool ReadData(ILocalizationManager localizationManager, string dictionaryAssetName, object dictionaryAsset, object userData); + + /// + /// 读取字典。 + /// + /// 本地化管理器。 + /// 字典资源名称。 + /// 字典二进制流。 + /// 字典二进制流的起始位置。 + /// 字典二进制流的长度。 + /// 用户自定义数据。 + /// 是否读取字典成功。 + public abstract bool ReadData(ILocalizationManager localizationManager, string dictionaryAssetName, byte[] dictionaryBytes, int startIndex, int length, object userData); + + /// + /// 解析字典。 + /// + /// 本地化管理器。 + /// 要解析的字典字符串。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public abstract bool ParseData(ILocalizationManager localizationManager, string dictionaryString, object userData); + + /// + /// 解析字典。 + /// + /// 本地化管理器。 + /// 要解析的字典二进制流。 + /// 字典二进制流的起始位置。 + /// 字典二进制流的长度。 + /// 用户自定义数据。 + /// 是否解析字典成功。 + public abstract bool ParseData(ILocalizationManager localizationManager, byte[] dictionaryBytes, int startIndex, int length, object userData); + + /// + /// 释放字典资源。 + /// + /// 本地化管理器。 + /// 要释放的字典资源。 + public abstract void ReleaseDataAsset(ILocalizationManager localizationManager, object dictionaryAsset); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationHelperBase.cs.meta new file mode 100644 index 0000000..da9a632 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Localization/LocalizationHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91f20cfd35b8d804ab29f8c3bc25fed8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network.meta new file mode 100644 index 0000000..99172e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e6bed9f3b15b3d64190301c8d908142a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkClosedEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkClosedEventArgs.cs new file mode 100644 index 0000000..0bb2e06 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkClosedEventArgs.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Network; + +namespace UnityGameFramework.Runtime +{ + /// + /// 网络连接关闭事件。 + /// + public sealed class NetworkClosedEventArgs : GameEventArgs + { + /// + /// 网络连接关闭事件编号。 + /// + public static readonly int EventId = typeof(NetworkClosedEventArgs).GetHashCode(); + + /// + /// 初始化网络连接关闭事件的新实例。 + /// + public NetworkClosedEventArgs() + { + NetworkChannel = null; + } + + /// + /// 获取网络连接关闭事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 创建网络连接关闭事件。 + /// + /// 内部事件。 + /// 创建的网络连接关闭事件。 + public static NetworkClosedEventArgs Create(GameFramework.Network.NetworkClosedEventArgs e) + { + NetworkClosedEventArgs networkClosedEventArgs = ReferencePool.Acquire(); + networkClosedEventArgs.NetworkChannel = e.NetworkChannel; + return networkClosedEventArgs; + } + + /// + /// 清理网络连接关闭事件。 + /// + public override void Clear() + { + NetworkChannel = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkClosedEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkClosedEventArgs.cs.meta new file mode 100644 index 0000000..44d3041 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkClosedEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47e152dade5b74240ae4e03d817452cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkComponent.cs new file mode 100644 index 0000000..9ae415b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkComponent.cs @@ -0,0 +1,152 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Network; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 网络组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Network")] + public sealed class NetworkComponent : GameFrameworkComponent + { + private INetworkManager m_NetworkManager = null; + private EventComponent m_EventComponent = null; + + /// + /// 获取网络频道数量。 + /// + public int NetworkChannelCount + { + get + { + return m_NetworkManager.NetworkChannelCount; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_NetworkManager = GameFrameworkEntry.GetModule(); + if (m_NetworkManager == null) + { + Log.Fatal("Network manager is invalid."); + return; + } + + m_NetworkManager.NetworkConnected += OnNetworkConnected; + m_NetworkManager.NetworkClosed += OnNetworkClosed; + m_NetworkManager.NetworkMissHeartBeat += OnNetworkMissHeartBeat; + m_NetworkManager.NetworkError += OnNetworkError; + m_NetworkManager.NetworkCustomError += OnNetworkCustomError; + } + + private void Start() + { + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + } + + /// + /// 检查是否存在网络频道。 + /// + /// 网络频道名称。 + /// 是否存在网络频道。 + public bool HasNetworkChannel(string name) + { + return m_NetworkManager.HasNetworkChannel(name); + } + + /// + /// 获取网络频道。 + /// + /// 网络频道名称。 + /// 要获取的网络频道。 + public INetworkChannel GetNetworkChannel(string name) + { + return m_NetworkManager.GetNetworkChannel(name); + } + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + public INetworkChannel[] GetAllNetworkChannels() + { + return m_NetworkManager.GetAllNetworkChannels(); + } + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + public void GetAllNetworkChannels(List results) + { + m_NetworkManager.GetAllNetworkChannels(results); + } + + /// + /// 创建网络频道。 + /// + /// 网络频道名称。 + /// 网络服务类型。 + /// 网络频道辅助器。 + /// 要创建的网络频道。 + public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper) + { + return m_NetworkManager.CreateNetworkChannel(name, serviceType, networkChannelHelper); + } + + /// + /// 销毁网络频道。 + /// + /// 网络频道名称。 + /// 是否销毁网络频道成功。 + public bool DestroyNetworkChannel(string name) + { + return m_NetworkManager.DestroyNetworkChannel(name); + } + + private void OnNetworkConnected(object sender, GameFramework.Network.NetworkConnectedEventArgs e) + { + m_EventComponent.Fire(this, NetworkConnectedEventArgs.Create(e)); + } + + private void OnNetworkClosed(object sender, GameFramework.Network.NetworkClosedEventArgs e) + { + m_EventComponent.Fire(this, NetworkClosedEventArgs.Create(e)); + } + + private void OnNetworkMissHeartBeat(object sender, GameFramework.Network.NetworkMissHeartBeatEventArgs e) + { + m_EventComponent.Fire(this, NetworkMissHeartBeatEventArgs.Create(e)); + } + + private void OnNetworkError(object sender, GameFramework.Network.NetworkErrorEventArgs e) + { + m_EventComponent.Fire(this, NetworkErrorEventArgs.Create(e)); + } + + private void OnNetworkCustomError(object sender, GameFramework.Network.NetworkCustomErrorEventArgs e) + { + m_EventComponent.Fire(this, NetworkCustomErrorEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkComponent.cs.meta new file mode 100644 index 0000000..ebf97f2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7afc859893311c34a8d8c2c426ab192d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkConnectedEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkConnectedEventArgs.cs new file mode 100644 index 0000000..c537376 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkConnectedEventArgs.cs @@ -0,0 +1,84 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Network; + +namespace UnityGameFramework.Runtime +{ + /// + /// 网络连接成功事件。 + /// + public sealed class NetworkConnectedEventArgs : GameEventArgs + { + /// + /// 网络连接成功事件编号。 + /// + public static readonly int EventId = typeof(NetworkConnectedEventArgs).GetHashCode(); + + /// + /// 初始化网络连接成功事件的新实例。 + /// + public NetworkConnectedEventArgs() + { + NetworkChannel = null; + UserData = null; + } + + /// + /// 获取网络连接成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建网络连接成功事件。 + /// + /// 内部事件。 + /// 创建的网络连接成功事件。 + public static NetworkConnectedEventArgs Create(GameFramework.Network.NetworkConnectedEventArgs e) + { + NetworkConnectedEventArgs networkConnectedEventArgs = ReferencePool.Acquire(); + networkConnectedEventArgs.NetworkChannel = e.NetworkChannel; + networkConnectedEventArgs.UserData = e.UserData; + return networkConnectedEventArgs; + } + + /// + /// 清理网络连接成功事件。 + /// + public override void Clear() + { + NetworkChannel = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkConnectedEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkConnectedEventArgs.cs.meta new file mode 100644 index 0000000..ac34ffc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkConnectedEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 980f3ac1c6457c64281b99ea2fc94384 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkCustomErrorEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkCustomErrorEventArgs.cs new file mode 100644 index 0000000..e9977e7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkCustomErrorEventArgs.cs @@ -0,0 +1,84 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Network; + +namespace UnityGameFramework.Runtime +{ + /// + /// 用户自定义网络错误事件。 + /// + public sealed class NetworkCustomErrorEventArgs : GameEventArgs + { + /// + /// 用户自定义网络错误事件编号。 + /// + public static readonly int EventId = typeof(NetworkCustomErrorEventArgs).GetHashCode(); + + /// + /// 初始化用户自定义网络错误事件的新实例。 + /// + public NetworkCustomErrorEventArgs() + { + NetworkChannel = null; + CustomErrorData = null; + } + + /// + /// 获取用户自定义网络错误事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 获取用户自定义错误数据。 + /// + public object CustomErrorData + { + get; + private set; + } + + /// + /// 创建用户自定义网络错误事件。 + /// + /// 内部事件。 + /// 创建的用户自定义网络错误事件。 + public static NetworkCustomErrorEventArgs Create(GameFramework.Network.NetworkCustomErrorEventArgs e) + { + NetworkCustomErrorEventArgs networkCustomErrorEventArgs = ReferencePool.Acquire(); + networkCustomErrorEventArgs.NetworkChannel = e.NetworkChannel; + networkCustomErrorEventArgs.CustomErrorData = e.CustomErrorData; + return networkCustomErrorEventArgs; + } + + /// + /// 清理用户自定义网络错误事件。 + /// + public override void Clear() + { + NetworkChannel = null; + CustomErrorData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkCustomErrorEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkCustomErrorEventArgs.cs.meta new file mode 100644 index 0000000..2edeecd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkCustomErrorEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a95c49efb7b92094a98ac60c420c06f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkErrorEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkErrorEventArgs.cs new file mode 100644 index 0000000..5997e22 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkErrorEventArgs.cs @@ -0,0 +1,107 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Network; +using System.Net.Sockets; + +namespace UnityGameFramework.Runtime +{ + /// + /// 网络错误事件。 + /// + public sealed class NetworkErrorEventArgs : GameEventArgs + { + /// + /// 网络错误事件编号。 + /// + public static readonly int EventId = typeof(NetworkErrorEventArgs).GetHashCode(); + + /// + /// 初始化网络错误事件的新实例。 + /// + public NetworkErrorEventArgs() + { + NetworkChannel = null; + ErrorCode = NetworkErrorCode.Unknown; + ErrorMessage = null; + } + + /// + /// 获取网络错误事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 获取错误码。 + /// + public NetworkErrorCode ErrorCode + { + get; + private set; + } + + /// + /// 获取 Socket 错误码。 + /// + public SocketError SocketErrorCode + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建网络错误事件。 + /// + /// 内部事件。 + /// 创建的网络错误事件。 + public static NetworkErrorEventArgs Create(GameFramework.Network.NetworkErrorEventArgs e) + { + NetworkErrorEventArgs networkErrorEventArgs = ReferencePool.Acquire(); + networkErrorEventArgs.NetworkChannel = e.NetworkChannel; + networkErrorEventArgs.ErrorCode = e.ErrorCode; + networkErrorEventArgs.SocketErrorCode = e.SocketErrorCode; + networkErrorEventArgs.ErrorMessage = e.ErrorMessage; + return networkErrorEventArgs; + } + + /// + /// 清理网络错误事件。 + /// + public override void Clear() + { + NetworkChannel = null; + ErrorCode = NetworkErrorCode.Unknown; + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkErrorEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkErrorEventArgs.cs.meta new file mode 100644 index 0000000..32e4efd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkErrorEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf09e20028671e24b97571df241445f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkMissHeartBeatEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkMissHeartBeatEventArgs.cs new file mode 100644 index 0000000..d327bc6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkMissHeartBeatEventArgs.cs @@ -0,0 +1,84 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Network; + +namespace UnityGameFramework.Runtime +{ + /// + /// 网络心跳包丢失事件。 + /// + public sealed class NetworkMissHeartBeatEventArgs : GameEventArgs + { + /// + /// 网络心跳包丢失事件编号。 + /// + public static readonly int EventId = typeof(NetworkMissHeartBeatEventArgs).GetHashCode(); + + /// + /// 初始化网络心跳包丢失事件的新实例。 + /// + public NetworkMissHeartBeatEventArgs() + { + NetworkChannel = null; + MissCount = 0; + } + + /// + /// 获取网络心跳包丢失事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取网络频道。 + /// + public INetworkChannel NetworkChannel + { + get; + private set; + } + + /// + /// 获取心跳包已丢失次数。 + /// + public int MissCount + { + get; + private set; + } + + /// + /// 创建网络心跳包丢失事件。 + /// + /// 内部事件。 + /// 创建的网络心跳包丢失事件。 + public static NetworkMissHeartBeatEventArgs Create(GameFramework.Network.NetworkMissHeartBeatEventArgs e) + { + NetworkMissHeartBeatEventArgs networkMissHeartBeatEventArgs = ReferencePool.Acquire(); + networkMissHeartBeatEventArgs.NetworkChannel = e.NetworkChannel; + networkMissHeartBeatEventArgs.MissCount = e.MissCount; + return networkMissHeartBeatEventArgs; + } + + /// + /// 清理网络心跳包丢失事件。 + /// + public override void Clear() + { + NetworkChannel = null; + MissCount = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkMissHeartBeatEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkMissHeartBeatEventArgs.cs.meta new file mode 100644 index 0000000..24947f1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Network/NetworkMissHeartBeatEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc1159a2cf0027947b397dbabbf4da4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool.meta new file mode 100644 index 0000000..2aad6b6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 82475e8acda14d045a5eee8e09f6bd9b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool/ObjectPoolComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool/ObjectPoolComponent.cs new file mode 100644 index 0000000..4f0cec0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool/ObjectPoolComponent.cs @@ -0,0 +1,1033 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.ObjectPool; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 对象池组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Object Pool")] + public sealed class ObjectPoolComponent : GameFrameworkComponent + { + private IObjectPoolManager m_ObjectPoolManager = null; + + /// + /// 获取对象池数量。 + /// + public int Count + { + get + { + return m_ObjectPoolManager.Count; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_ObjectPoolManager = GameFrameworkEntry.GetModule(); + if (m_ObjectPoolManager == null) + { + Log.Fatal("Object pool manager is invalid."); + return; + } + } + + private void Start() + { + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 是否存在对象池。 + public bool HasObjectPool() where T : ObjectBase + { + return m_ObjectPoolManager.HasObjectPool(); + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 是否存在对象池。 + public bool HasObjectPool(Type objectType) + { + return m_ObjectPoolManager.HasObjectPool(objectType); + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 是否存在对象池。 + public bool HasObjectPool(string name) where T : ObjectBase + { + return m_ObjectPoolManager.HasObjectPool(name); + } + + /// + /// 检查是否存在对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 是否存在对象池。 + public bool HasObjectPool(Type objectType, string name) + { + return m_ObjectPoolManager.HasObjectPool(objectType, name); + } + + /// + /// 检查是否存在对象池。 + /// + /// 要检查的条件。 + /// 是否存在对象池。 + public bool HasObjectPool(Predicate condition) + { + return m_ObjectPoolManager.HasObjectPool(condition); + } + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 要获取的对象池。 + public IObjectPool GetObjectPool() where T : ObjectBase + { + return m_ObjectPoolManager.GetObjectPool(); + } + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 要获取的对象池。 + public ObjectPoolBase GetObjectPool(Type objectType) + { + return m_ObjectPoolManager.GetObjectPool(objectType); + } + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要获取的对象池。 + public IObjectPool GetObjectPool(string name) where T : ObjectBase + { + return m_ObjectPoolManager.GetObjectPool(name); + } + + /// + /// 获取对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要获取的对象池。 + public ObjectPoolBase GetObjectPool(Type objectType, string name) + { + return m_ObjectPoolManager.GetObjectPool(objectType, name); + } + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + public ObjectPoolBase GetObjectPool(Predicate condition) + { + return m_ObjectPoolManager.GetObjectPool(condition); + } + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + public ObjectPoolBase[] GetObjectPools(Predicate condition) + { + return m_ObjectPoolManager.GetObjectPools(condition); + } + + /// + /// 获取对象池。 + /// + /// 要检查的条件。 + /// 要获取的对象池。 + public void GetObjectPools(Predicate condition, List results) + { + m_ObjectPoolManager.GetObjectPools(condition, results); + } + + /// + /// 获取所有对象池。 + /// + public ObjectPoolBase[] GetAllObjectPools() + { + return m_ObjectPoolManager.GetAllObjectPools(); + } + + /// + /// 获取所有对象池。 + /// + /// 所有对象池。 + public void GetAllObjectPools(List results) + { + m_ObjectPoolManager.GetAllObjectPools(results); + } + + /// + /// 获取所有对象池。 + /// + /// 是否根据对象池的优先级排序。 + /// 所有对象池。 + public ObjectPoolBase[] GetAllObjectPools(bool sort) + { + return m_ObjectPoolManager.GetAllObjectPools(sort); + } + + /// + /// 获取所有对象池。 + /// + /// 是否根据对象池的优先级排序。 + /// 所有对象池。 + public void GetAllObjectPools(bool sort, List results) + { + m_ObjectPoolManager.GetAllObjectPools(sort, results); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool() where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(name); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, name); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(int capacity) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(capacity); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, capacity); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(float expireTime) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(expireTime); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, expireTime); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, int capacity) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(name, capacity); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, name, capacity); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, float expireTime) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(name, expireTime); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, name, expireTime); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(int capacity, float expireTime) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(capacity, expireTime); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, capacity, expireTime); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(int capacity, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(capacity, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, int priority) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, capacity, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, float expireTime) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(name, capacity, expireTime); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, name, capacity, expireTime); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(name, capacity, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, int priority) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, name, capacity, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(name, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, name, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(int capacity, float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, int capacity, float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(name, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, name, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public IObjectPool CreateSingleSpawnObjectPool(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(name, autoReleaseInterval, capacity, expireTime, priority); + } + + /// + /// 创建允许单次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许单次获取的对象池。 + public ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateSingleSpawnObjectPool(objectType, name, autoReleaseInterval, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool() where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(name); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, name); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(int capacity) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(capacity); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, capacity); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(float expireTime) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(expireTime); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, expireTime); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, int capacity) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(name, capacity); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, name, capacity); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, float expireTime) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(name, expireTime); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, name, expireTime); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(int capacity, float expireTime) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(capacity, expireTime); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, capacity, expireTime); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(int capacity, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(capacity, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, int priority) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, capacity, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, float expireTime) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(name, capacity, expireTime); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, name, capacity, expireTime); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(name, capacity, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, int priority) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, name, capacity, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(name, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, name, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(int capacity, float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, int capacity, float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(name, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, name, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public IObjectPool CreateMultiSpawnObjectPool(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(name, autoReleaseInterval, capacity, expireTime, priority); + } + + /// + /// 创建允许多次获取的对象池。 + /// + /// 对象类型。 + /// 对象池名称。 + /// 对象池自动释放可释放对象的间隔秒数。 + /// 对象池的容量。 + /// 对象池对象过期秒数。 + /// 对象池的优先级。 + /// 要创建的允许多次获取的对象池。 + public ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority) + { + return m_ObjectPoolManager.CreateMultiSpawnObjectPool(objectType, name, autoReleaseInterval, capacity, expireTime, priority); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool() where T : ObjectBase + { + return m_ObjectPoolManager.DestroyObjectPool(); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(Type objectType) + { + return m_ObjectPoolManager.DestroyObjectPool(objectType); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池名称。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(string name) where T : ObjectBase + { + return m_ObjectPoolManager.DestroyObjectPool(name); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池名称。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(Type objectType, string name) + { + return m_ObjectPoolManager.DestroyObjectPool(objectType, name); + } + + /// + /// 销毁对象池。 + /// + /// 对象类型。 + /// 要销毁的对象池。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(IObjectPool objectPool) where T : ObjectBase + { + return m_ObjectPoolManager.DestroyObjectPool(objectPool); + } + + /// + /// 销毁对象池。 + /// + /// 要销毁的对象池。 + /// 是否销毁对象池成功。 + public bool DestroyObjectPool(ObjectPoolBase objectPool) + { + return m_ObjectPoolManager.DestroyObjectPool(objectPool); + } + + /// + /// 释放对象池中的可释放对象。 + /// + public void Release() + { + Log.Info("Object pool release..."); + m_ObjectPoolManager.Release(); + } + + /// + /// 释放对象池中的所有未使用对象。 + /// + public void ReleaseAllUnused() + { + Log.Info("Object pool release all unused..."); + m_ObjectPoolManager.ReleaseAllUnused(); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool/ObjectPoolComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool/ObjectPoolComponent.cs.meta new file mode 100644 index 0000000..432ece2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ObjectPool/ObjectPoolComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e28a727443c86c40aeb42ff20e0a343 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure.meta new file mode 100644 index 0000000..7bad022 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1311dfda55b638740a95b1bba894a2e8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure/ProcedureComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure/ProcedureComponent.cs new file mode 100644 index 0000000..6b19257 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure/ProcedureComponent.cs @@ -0,0 +1,162 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Fsm; +using GameFramework.Procedure; +using System; +using System.Collections; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 流程组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Procedure")] + public sealed class ProcedureComponent : GameFrameworkComponent + { + private IProcedureManager m_ProcedureManager = null; + private ProcedureBase m_EntranceProcedure = null; + + [SerializeField] + private string[] m_AvailableProcedureTypeNames = null; + //private string[] m_AvailableProcedureTypeNames = new string[] + //{ + // "ProcedureCheckResources", + // "ProcedureCheckVersion", + // "ProcedureInitResources", + // "ProcedureLaunch", + // "ProcedureMenu", + // "ProcedurePreload", + // "ProcedureSplash", + // "ProcedureUpdateResources", + // "ProcedureUpdateVersion", + // "ProcedureVerifyResources", + //}; + + [SerializeField] + private string m_EntranceProcedureTypeName = null; + //private string m_EntranceProcedureTypeName = "ProcedureLaunch"; + + /// + /// 获取当前流程。 + /// + public ProcedureBase CurrentProcedure + { + get + { + return m_ProcedureManager.CurrentProcedure; + } + } + + /// + /// 获取当前流程持续时间。 + /// + public float CurrentProcedureTime + { + get + { + return m_ProcedureManager.CurrentProcedureTime; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_ProcedureManager = GameFrameworkEntry.GetModule(); + if (m_ProcedureManager == null) + { + Log.Fatal("Procedure manager is invalid."); + return; + } + } + + private IEnumerator Start() + { + ProcedureBase[] procedures = new ProcedureBase[m_AvailableProcedureTypeNames.Length]; + for (int i = 0; i < m_AvailableProcedureTypeNames.Length; i++) + { + Type procedureType = Utility.Assembly.GetType(m_AvailableProcedureTypeNames[i]); + if (procedureType == null) + { + Log.Error("Can not find procedure type '{0}'.", m_AvailableProcedureTypeNames[i]); + yield break; + } + + procedures[i] = (ProcedureBase)Activator.CreateInstance(procedureType); + if (procedures[i] == null) + { + Log.Error("Can not create procedure instance '{0}'.", m_AvailableProcedureTypeNames[i]); + yield break; + } + + if (m_EntranceProcedureTypeName == m_AvailableProcedureTypeNames[i]) + { + m_EntranceProcedure = procedures[i]; + } + } + + if (m_EntranceProcedure == null) + { + Log.Error("Entrance procedure is invalid."); + yield break; + } + + m_ProcedureManager.Initialize(GameFrameworkEntry.GetModule(), procedures); + + yield return new WaitForEndOfFrame(); + + m_ProcedureManager.StartProcedure(m_EntranceProcedure.GetType()); + } + + /// + /// 是否存在流程。 + /// + /// 要检查的流程类型。 + /// 是否存在流程。 + public bool HasProcedure() where T : ProcedureBase + { + return m_ProcedureManager.HasProcedure(); + } + + /// + /// 是否存在流程。 + /// + /// 要检查的流程类型。 + /// 是否存在流程。 + public bool HasProcedure(Type procedureType) + { + return m_ProcedureManager.HasProcedure(procedureType); + } + + /// + /// 获取流程。 + /// + /// 要获取的流程类型。 + /// 要获取的流程。 + public ProcedureBase GetProcedure() where T : ProcedureBase + { + return m_ProcedureManager.GetProcedure(); + } + + /// + /// 获取流程。 + /// + /// 要获取的流程类型。 + /// 要获取的流程。 + public ProcedureBase GetProcedure(Type procedureType) + { + return m_ProcedureManager.GetProcedure(procedureType); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure/ProcedureComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure/ProcedureComponent.cs.meta new file mode 100644 index 0000000..fb371df --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Procedure/ProcedureComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 959bca2b68d03954897f38b1dbb00303 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool.meta new file mode 100644 index 0000000..86555f9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d8ddcb97e04c6d94aaabafc2ae83cb2b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferencePoolComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferencePoolComponent.cs new file mode 100644 index 0000000..818d8ad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferencePoolComponent.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 引用池组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/ReferencePool")] + public sealed class ReferencePoolComponent : GameFrameworkComponent + { + [SerializeField] + private ReferenceStrictCheckType m_EnableStrictCheck = ReferenceStrictCheckType.AlwaysEnable; + + /// + /// 获取或设置是否开启强制检查。 + /// + public bool EnableStrictCheck + { + get + { + return ReferencePool.EnableStrictCheck; + } + set + { + ReferencePool.EnableStrictCheck = value; + if (value) + { + Log.Info("Strict checking is enabled for the Reference Pool. It will drastically affect the performance."); + } + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + } + + private void Start() + { + switch (m_EnableStrictCheck) + { + case ReferenceStrictCheckType.AlwaysEnable: + EnableStrictCheck = true; + break; + + case ReferenceStrictCheckType.OnlyEnableWhenDevelopment: + EnableStrictCheck = Debug.isDebugBuild; + break; + + case ReferenceStrictCheckType.OnlyEnableInEditor: + EnableStrictCheck = Application.isEditor; + break; + + default: + EnableStrictCheck = false; + break; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferencePoolComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferencePoolComponent.cs.meta new file mode 100644 index 0000000..df72488 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferencePoolComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ae4d40d7e878bc498492dc9c410d071 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferenceStrictCheckType.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferenceStrictCheckType.cs new file mode 100644 index 0000000..4293c90 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferenceStrictCheckType.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + /// + /// 引用强制检查类型。 + /// + public enum ReferenceStrictCheckType : byte + { + /// + /// 总是启用。 + /// + AlwaysEnable = 0, + + /// + /// 仅在开发模式时启用。 + /// + OnlyEnableWhenDevelopment, + + /// + /// 仅在编辑器中启用。 + /// + OnlyEnableInEditor, + + /// + /// 总是禁用。 + /// + AlwaysDisable, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferenceStrictCheckType.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferenceStrictCheckType.cs.meta new file mode 100644 index 0000000..bd6c893 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/ReferencePool/ReferenceStrictCheckType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1abf21b782f0fec40bd37a5f17124b83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource.meta new file mode 100644 index 0000000..da52a6e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bfb05af2569429d4c9181594977155d9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListDeserializeCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListDeserializeCallback.cs new file mode 100644 index 0000000..bdafd50 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListDeserializeCallback.cs @@ -0,0 +1,114 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { + /// + /// 反序列化本地版本资源列表(版本 0)回调函数。 + /// + /// 指定流。 + /// 反序列化的本地版本资源列表(版本 0)。 + public static LocalVersionList LocalVersionListDeserializeCallback_V0(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + int resourceCount = binaryReader.ReadInt32(); + LocalVersionList.Resource[] resources = resourceCount > 0 ? new LocalVersionList.Resource[resourceCount] : null; + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.ReadInt32(); + int hashCode = binaryReader.ReadInt32(); + resources[i] = new LocalVersionList.Resource(name, variant, null, loadType, length, hashCode); + } + + return new LocalVersionList(resources, null); + } + } + + /// + /// 反序列化本地版本资源列表(版本 1)回调函数。 + /// + /// 指定流。 + /// 反序列化的本地版本资源列表(版本 1)。 + public static LocalVersionList LocalVersionListDeserializeCallback_V1(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + int resourceCount = binaryReader.Read7BitEncodedInt32(); + LocalVersionList.Resource[] resources = resourceCount > 0 ? new LocalVersionList.Resource[resourceCount] : null; + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + string extension = binaryReader.ReadEncryptedString(encryptBytes) ?? DefaultExtension; + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.Read7BitEncodedInt32(); + int hashCode = binaryReader.ReadInt32(); + resources[i] = new LocalVersionList.Resource(name, variant, extension, loadType, length, hashCode); + } + + return new LocalVersionList(resources, null); + } + } + + /// + /// 反序列化本地版本资源列表(版本 2)回调函数。 + /// + /// 指定流。 + /// 反序列化的本地版本资源列表(版本 2)。 + public static LocalVersionList LocalVersionListDeserializeCallback_V2(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + int resourceCount = binaryReader.Read7BitEncodedInt32(); + LocalVersionList.Resource[] resources = resourceCount > 0 ? new LocalVersionList.Resource[resourceCount] : null; + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + string extension = binaryReader.ReadEncryptedString(encryptBytes) ?? DefaultExtension; + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.Read7BitEncodedInt32(); + int hashCode = binaryReader.ReadInt32(); + resources[i] = new LocalVersionList.Resource(name, variant, extension, loadType, length, hashCode); + } + + int fileSystemCount = binaryReader.Read7BitEncodedInt32(); + LocalVersionList.FileSystem[] fileSystems = fileSystemCount > 0 ? new LocalVersionList.FileSystem[fileSystemCount] : null; + for (int i = 0; i < fileSystemCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + fileSystems[i] = new LocalVersionList.FileSystem(name, resourceIndexes); + } + + return new LocalVersionList(resources, fileSystems); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListDeserializeCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListDeserializeCallback.cs.meta new file mode 100644 index 0000000..c57ed16 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListDeserializeCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df66ad097f961904fb7bca9ea86b226f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListSerializeCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListSerializeCallback.cs new file mode 100644 index 0000000..faabcc5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListSerializeCallback.cs @@ -0,0 +1,135 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +using System; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { + /// + /// 序列化本地版本资源列表(版本 0)回调函数。 + /// + /// 目标流。 + /// 要序列化的本地版本资源列表(版本 0)。 + /// 是否序列化本地版本资源列表(版本 0)成功。 + public static bool LocalVersionListSerializeCallback_V0(Stream stream, LocalVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + LocalVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write(resources.Length); + foreach (LocalVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write(resource.Length); + binaryWriter.Write(resource.HashCode); + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + + /// + /// 序列化本地版本资源列表(版本 1)回调函数。 + /// + /// 目标流。 + /// 要序列化的本地版本资源列表(版本 1)。 + /// 是否序列化本地版本资源列表(版本 1)成功。 + public static bool LocalVersionListSerializeCallback_V1(Stream stream, LocalVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + LocalVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write7BitEncodedInt32(resources.Length); + foreach (LocalVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Extension != DefaultExtension ? resource.Extension : null, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write7BitEncodedInt32(resource.Length); + binaryWriter.Write(resource.HashCode); + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + + /// + /// 序列化本地版本资源列表(版本 2)回调函数。 + /// + /// 目标流。 + /// 要序列化的本地版本资源列表(版本 2)。 + /// 是否序列化本地版本资源列表(版本 2)成功。 + public static bool LocalVersionListSerializeCallback_V2(Stream stream, LocalVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + LocalVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write7BitEncodedInt32(resources.Length); + foreach (LocalVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Extension != DefaultExtension ? resource.Extension : null, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write7BitEncodedInt32(resource.Length); + binaryWriter.Write(resource.HashCode); + } + + LocalVersionList.FileSystem[] fileSystems = versionList.GetFileSystems(); + binaryWriter.Write7BitEncodedInt32(fileSystems.Length); + foreach (LocalVersionList.FileSystem fileSystem in fileSystems) + { + binaryWriter.WriteEncryptedString(fileSystem.Name, s_CachedHashBytes); + int[] resourceIndexes = fileSystem.GetResourceIndexes(); + binaryWriter.Write7BitEncodedInt32(resourceIndexes.Length); + foreach (int resourceIndex in resourceIndexes) + { + binaryWriter.Write7BitEncodedInt32(resourceIndex); + } + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListSerializeCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListSerializeCallback.cs.meta new file mode 100644 index 0000000..f9df195 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.LocalVersionListSerializeCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7633b95b6d880174bbf537a35e918141 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListDeserializeCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListDeserializeCallback.cs new file mode 100644 index 0000000..665a758 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListDeserializeCallback.cs @@ -0,0 +1,264 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { + /// + /// 反序列化单机模式版本资源列表(版本 0)回调函数。 + /// + /// 指定流。 + /// 反序列化的单机模式版本资源列表(版本 0)。 + public static PackageVersionList PackageVersionListDeserializeCallback_V0(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + string applicableGameVersion = binaryReader.ReadEncryptedString(encryptBytes); + int internalResourceVersion = binaryReader.ReadInt32(); + int assetCount = binaryReader.ReadInt32(); + PackageVersionList.Asset[] assets = assetCount > 0 ? new PackageVersionList.Asset[assetCount] : null; + int resourceCount = binaryReader.ReadInt32(); + PackageVersionList.Resource[] resources = resourceCount > 0 ? new PackageVersionList.Resource[resourceCount] : null; + string[][] resourceToAssetNames = new string[resourceCount][]; + List> assetNameToDependencyAssetNames = new List>(assetCount); + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.ReadInt32(); + int hashCode = binaryReader.ReadInt32(); + Utility.Converter.GetBytes(hashCode, s_CachedHashBytes); + + int assetNameCount = binaryReader.ReadInt32(); + string[] assetNames = new string[assetNameCount]; + for (int j = 0; j < assetNameCount; j++) + { + assetNames[j] = binaryReader.ReadEncryptedString(s_CachedHashBytes); + int dependencyAssetNameCount = binaryReader.ReadInt32(); + string[] dependencyAssetNames = dependencyAssetNameCount > 0 ? new string[dependencyAssetNameCount] : null; + for (int k = 0; k < dependencyAssetNameCount; k++) + { + dependencyAssetNames[k] = binaryReader.ReadEncryptedString(s_CachedHashBytes); + } + + assetNameToDependencyAssetNames.Add(new KeyValuePair(assetNames[j], dependencyAssetNames)); + } + + resourceToAssetNames[i] = assetNames; + resources[i] = new PackageVersionList.Resource(name, variant, null, loadType, length, hashCode, assetNameCount > 0 ? new int[assetNameCount] : null); + } + + assetNameToDependencyAssetNames.Sort(AssetNameToDependencyAssetNamesComparer); + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + int index = 0; + foreach (KeyValuePair i in assetNameToDependencyAssetNames) + { + if (i.Value != null) + { + int[] dependencyAssetIndexes = new int[i.Value.Length]; + for (int j = 0; j < i.Value.Length; j++) + { + dependencyAssetIndexes[j] = GetAssetNameIndex(assetNameToDependencyAssetNames, i.Value[j]); + } + + assets[index++] = new PackageVersionList.Asset(i.Key, dependencyAssetIndexes); + } + else + { + assets[index++] = new PackageVersionList.Asset(i.Key, null); + } + } + + for (int i = 0; i < resources.Length; i++) + { + int[] assetIndexes = resources[i].GetAssetIndexes(); + for (int j = 0; j < assetIndexes.Length; j++) + { + assetIndexes[j] = GetAssetNameIndex(assetNameToDependencyAssetNames, resourceToAssetNames[i][j]); + } + } + + int resourceGroupCount = binaryReader.ReadInt32(); + PackageVersionList.ResourceGroup[] resourceGroups = resourceGroupCount > 0 ? new PackageVersionList.ResourceGroup[resourceGroupCount] : null; + for (int i = 0; i < resourceGroupCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.ReadInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.ReadUInt16(); + } + + resourceGroups[i] = new PackageVersionList.ResourceGroup(name, resourceIndexes); + } + + return new PackageVersionList(applicableGameVersion, internalResourceVersion, assets, resources, null, resourceGroups); + } + } + + /// + /// 反序列化单机模式版本资源列表(版本 1)回调函数。 + /// + /// 指定流。 + /// 反序列化的单机模式版本资源列表(版本 1)。 + public static PackageVersionList PackageVersionListDeserializeCallback_V1(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + string applicableGameVersion = binaryReader.ReadEncryptedString(encryptBytes); + int internalResourceVersion = binaryReader.Read7BitEncodedInt32(); + int assetCount = binaryReader.Read7BitEncodedInt32(); + PackageVersionList.Asset[] assets = assetCount > 0 ? new PackageVersionList.Asset[assetCount] : null; + for (int i = 0; i < assetCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int dependencyAssetCount = binaryReader.Read7BitEncodedInt32(); + int[] dependencyAssetIndexes = dependencyAssetCount > 0 ? new int[dependencyAssetCount] : null; + for (int j = 0; j < dependencyAssetCount; j++) + { + dependencyAssetIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + assets[i] = new PackageVersionList.Asset(name, dependencyAssetIndexes); + } + + int resourceCount = binaryReader.Read7BitEncodedInt32(); + PackageVersionList.Resource[] resources = resourceCount > 0 ? new PackageVersionList.Resource[resourceCount] : null; + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + string extension = binaryReader.ReadEncryptedString(encryptBytes) ?? DefaultExtension; + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.Read7BitEncodedInt32(); + int hashCode = binaryReader.ReadInt32(); + int assetIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] assetIndexes = assetIndexCount > 0 ? new int[assetIndexCount] : null; + for (int j = 0; j < assetIndexCount; j++) + { + assetIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + resources[i] = new PackageVersionList.Resource(name, variant, extension, loadType, length, hashCode, assetIndexes); + } + + int resourceGroupCount = binaryReader.Read7BitEncodedInt32(); + PackageVersionList.ResourceGroup[] resourceGroups = resourceGroupCount > 0 ? new PackageVersionList.ResourceGroup[resourceGroupCount] : null; + for (int i = 0; i < resourceGroupCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + resourceGroups[i] = new PackageVersionList.ResourceGroup(name, resourceIndexes); + } + + return new PackageVersionList(applicableGameVersion, internalResourceVersion, assets, resources, null, resourceGroups); + } + } + + /// + /// 反序列化单机模式版本资源列表(版本 2)回调函数。 + /// + /// 指定流。 + /// 反序列化的单机模式版本资源列表(版本 2)。 + public static PackageVersionList PackageVersionListDeserializeCallback_V2(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + string applicableGameVersion = binaryReader.ReadEncryptedString(encryptBytes); + int internalResourceVersion = binaryReader.Read7BitEncodedInt32(); + int assetCount = binaryReader.Read7BitEncodedInt32(); + PackageVersionList.Asset[] assets = assetCount > 0 ? new PackageVersionList.Asset[assetCount] : null; + for (int i = 0; i < assetCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int dependencyAssetCount = binaryReader.Read7BitEncodedInt32(); + int[] dependencyAssetIndexes = dependencyAssetCount > 0 ? new int[dependencyAssetCount] : null; + for (int j = 0; j < dependencyAssetCount; j++) + { + dependencyAssetIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + assets[i] = new PackageVersionList.Asset(name, dependencyAssetIndexes); + } + + int resourceCount = binaryReader.Read7BitEncodedInt32(); + PackageVersionList.Resource[] resources = resourceCount > 0 ? new PackageVersionList.Resource[resourceCount] : null; + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + string extension = binaryReader.ReadEncryptedString(encryptBytes) ?? DefaultExtension; + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.Read7BitEncodedInt32(); + int hashCode = binaryReader.ReadInt32(); + int assetIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] assetIndexes = assetIndexCount > 0 ? new int[assetIndexCount] : null; + for (int j = 0; j < assetIndexCount; j++) + { + assetIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + resources[i] = new PackageVersionList.Resource(name, variant, extension, loadType, length, hashCode, assetIndexes); + } + + int fileSystemCount = binaryReader.Read7BitEncodedInt32(); + PackageVersionList.FileSystem[] fileSystems = fileSystemCount > 0 ? new PackageVersionList.FileSystem[fileSystemCount] : null; + for (int i = 0; i < fileSystemCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + fileSystems[i] = new PackageVersionList.FileSystem(name, resourceIndexes); + } + + int resourceGroupCount = binaryReader.Read7BitEncodedInt32(); + PackageVersionList.ResourceGroup[] resourceGroups = resourceGroupCount > 0 ? new PackageVersionList.ResourceGroup[resourceGroupCount] : null; + for (int i = 0; i < resourceGroupCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + resourceGroups[i] = new PackageVersionList.ResourceGroup(name, resourceIndexes); + } + + return new PackageVersionList(applicableGameVersion, internalResourceVersion, assets, resources, fileSystems, resourceGroups); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListDeserializeCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListDeserializeCallback.cs.meta new file mode 100644 index 0000000..9d5ad27 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListDeserializeCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55d016c3660f4fa458c20847cf59aa16 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListSerializeCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListSerializeCallback.cs new file mode 100644 index 0000000..f07b3fd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListSerializeCallback.cs @@ -0,0 +1,239 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +using System; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { +#if UNITY_EDITOR + + /// + /// 序列化单机模式版本资源列表(版本 0)回调函数。 + /// + /// 目标流。 + /// 要序列化的单机模式版本资源列表(版本 0)。 + /// 是否序列化单机模式版本资源列表(版本 0)成功。 + public static bool PackageVersionListSerializeCallback_V0(Stream stream, PackageVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + binaryWriter.WriteEncryptedString(versionList.ApplicableGameVersion, s_CachedHashBytes); + binaryWriter.Write(versionList.InternalResourceVersion); + PackageVersionList.Asset[] assets = versionList.GetAssets(); + binaryWriter.Write(assets.Length); + PackageVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write(resources.Length); + foreach (PackageVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write(resource.Length); + binaryWriter.Write(resource.HashCode); + int[] assetIndexes = resource.GetAssetIndexes(); + binaryWriter.Write(assetIndexes.Length); + byte[] hashBytes = new byte[CachedHashBytesLength]; + foreach (int assetIndex in assetIndexes) + { + Utility.Converter.GetBytes(resource.HashCode, hashBytes); + PackageVersionList.Asset asset = assets[assetIndex]; + binaryWriter.WriteEncryptedString(asset.Name, hashBytes); + int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); + binaryWriter.Write(dependencyAssetIndexes.Length); + foreach (int dependencyAssetIndex in dependencyAssetIndexes) + { + binaryWriter.WriteEncryptedString(assets[dependencyAssetIndex].Name, hashBytes); + } + } + } + + PackageVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); + binaryWriter.Write(resourceGroups.Length); + foreach (PackageVersionList.ResourceGroup resourceGroup in resourceGroups) + { + binaryWriter.WriteEncryptedString(resourceGroup.Name, s_CachedHashBytes); + int[] resourceIndexes = resourceGroup.GetResourceIndexes(); + binaryWriter.Write(resourceIndexes.Length); + foreach (ushort resourceIndex in resourceIndexes) + { + binaryWriter.Write(resourceIndex); + } + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + + /// + /// 序列化单机模式版本资源列表(版本 1)回调函数。 + /// + /// 目标流。 + /// 要序列化的单机模式版本资源列表(版本 1)。 + /// 是否序列化单机模式版本资源列表(版本 1)成功。 + public static bool PackageVersionListSerializeCallback_V1(Stream stream, PackageVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + binaryWriter.WriteEncryptedString(versionList.ApplicableGameVersion, s_CachedHashBytes); + binaryWriter.Write7BitEncodedInt32(versionList.InternalResourceVersion); + PackageVersionList.Asset[] assets = versionList.GetAssets(); + binaryWriter.Write7BitEncodedInt32(assets.Length); + foreach (PackageVersionList.Asset asset in assets) + { + binaryWriter.WriteEncryptedString(asset.Name, s_CachedHashBytes); + int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); + binaryWriter.Write7BitEncodedInt32(dependencyAssetIndexes.Length); + foreach (int dependencyAssetIndex in dependencyAssetIndexes) + { + binaryWriter.Write7BitEncodedInt32(dependencyAssetIndex); + } + } + + PackageVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write7BitEncodedInt32(resources.Length); + foreach (PackageVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Extension != DefaultExtension ? resource.Extension : null, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write7BitEncodedInt32(resource.Length); + binaryWriter.Write(resource.HashCode); + int[] assetIndexes = resource.GetAssetIndexes(); + binaryWriter.Write7BitEncodedInt32(assetIndexes.Length); + foreach (int assetIndex in assetIndexes) + { + binaryWriter.Write7BitEncodedInt32(assetIndex); + } + } + + PackageVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); + binaryWriter.Write7BitEncodedInt32(resourceGroups.Length); + foreach (PackageVersionList.ResourceGroup resourceGroup in resourceGroups) + { + binaryWriter.WriteEncryptedString(resourceGroup.Name, s_CachedHashBytes); + int[] resourceIndexes = resourceGroup.GetResourceIndexes(); + binaryWriter.Write7BitEncodedInt32(resourceIndexes.Length); + foreach (int resourceIndex in resourceIndexes) + { + binaryWriter.Write7BitEncodedInt32(resourceIndex); + } + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + + /// + /// 序列化单机模式版本资源列表(版本 2)回调函数。 + /// + /// 目标流。 + /// 要序列化的单机模式版本资源列表(版本 2)。 + /// 是否序列化单机模式版本资源列表(版本 2)成功。 + public static bool PackageVersionListSerializeCallback_V2(Stream stream, PackageVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + binaryWriter.WriteEncryptedString(versionList.ApplicableGameVersion, s_CachedHashBytes); + binaryWriter.Write7BitEncodedInt32(versionList.InternalResourceVersion); + PackageVersionList.Asset[] assets = versionList.GetAssets(); + binaryWriter.Write7BitEncodedInt32(assets.Length); + foreach (PackageVersionList.Asset asset in assets) + { + binaryWriter.WriteEncryptedString(asset.Name, s_CachedHashBytes); + int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); + binaryWriter.Write7BitEncodedInt32(dependencyAssetIndexes.Length); + foreach (int dependencyAssetIndex in dependencyAssetIndexes) + { + binaryWriter.Write7BitEncodedInt32(dependencyAssetIndex); + } + } + + PackageVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write7BitEncodedInt32(resources.Length); + foreach (PackageVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Extension != DefaultExtension ? resource.Extension : null, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write7BitEncodedInt32(resource.Length); + binaryWriter.Write(resource.HashCode); + int[] assetIndexes = resource.GetAssetIndexes(); + binaryWriter.Write7BitEncodedInt32(assetIndexes.Length); + foreach (int assetIndex in assetIndexes) + { + binaryWriter.Write7BitEncodedInt32(assetIndex); + } + } + + PackageVersionList.FileSystem[] fileSystems = versionList.GetFileSystems(); + binaryWriter.Write7BitEncodedInt32(fileSystems.Length); + foreach (PackageVersionList.FileSystem fileSystem in fileSystems) + { + binaryWriter.WriteEncryptedString(fileSystem.Name, s_CachedHashBytes); + int[] resourceIndexes = fileSystem.GetResourceIndexes(); + binaryWriter.Write7BitEncodedInt32(resourceIndexes.Length); + foreach (int resourceIndex in resourceIndexes) + { + binaryWriter.Write7BitEncodedInt32(resourceIndex); + } + } + + PackageVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); + binaryWriter.Write7BitEncodedInt32(resourceGroups.Length); + foreach (PackageVersionList.ResourceGroup resourceGroup in resourceGroups) + { + binaryWriter.WriteEncryptedString(resourceGroup.Name, s_CachedHashBytes); + int[] resourceIndexes = resourceGroup.GetResourceIndexes(); + binaryWriter.Write7BitEncodedInt32(resourceIndexes.Length); + foreach (int resourceIndex in resourceIndexes) + { + binaryWriter.Write7BitEncodedInt32(resourceIndex); + } + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + +#endif + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListSerializeCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListSerializeCallback.cs.meta new file mode 100644 index 0000000..39b29ad --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.PackageVersionListSerializeCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f1e0304275244949890ac3aa8a7f236 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback.cs new file mode 100644 index 0000000..a95bceb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { + /// + /// 反序列化资源包版本资源列表(版本 0)回调函数。 + /// + /// 指定流。 + /// 反序列化的资源包版本资源列表(版本 0)。 + public static ResourcePackVersionList ResourcePackVersionListDeserializeCallback_V0(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + int dataOffset = binaryReader.ReadInt32(); + long dataLength = binaryReader.ReadInt64(); + int dataHashCode = binaryReader.ReadInt32(); + int resourceCount = binaryReader.Read7BitEncodedInt32(); + ResourcePackVersionList.Resource[] resources = resourceCount > 0 ? new ResourcePackVersionList.Resource[resourceCount] : null; + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + string extension = binaryReader.ReadEncryptedString(encryptBytes) ?? DefaultExtension; + byte loadType = binaryReader.ReadByte(); + long offset = binaryReader.Read7BitEncodedInt64(); + int length = binaryReader.Read7BitEncodedInt32(); + int hashCode = binaryReader.ReadInt32(); + int compressedLength = binaryReader.Read7BitEncodedInt32(); + int compressedHashCode = binaryReader.ReadInt32(); + resources[i] = new ResourcePackVersionList.Resource(name, variant, extension, loadType, offset, length, hashCode, compressedLength, compressedHashCode); + } + + return new ResourcePackVersionList(dataOffset, dataLength, dataHashCode, resources); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback.cs.meta new file mode 100644 index 0000000..45413f9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 03b37f88eb002e740881c81bba3ac02b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback.cs new file mode 100644 index 0000000..b2514fb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +using System; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { +#if UNITY_EDITOR + + /// + /// 序列化资源包版本资源列表(版本 0)回调函数。 + /// + /// 目标流。 + /// 要序列化的资源包版本资源列表(版本 0)。 + /// 是否序列化资源包版本资源列表(版本 0)成功。 + public static bool ResourcePackVersionListSerializeCallback_V0(Stream stream, ResourcePackVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + binaryWriter.Write(versionList.Offset); + binaryWriter.Write(versionList.Length); + binaryWriter.Write(versionList.HashCode); + ResourcePackVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write7BitEncodedInt32(resources.Length); + foreach (ResourcePackVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Extension != DefaultExtension ? resource.Extension : null, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write7BitEncodedInt64(resource.Offset); + binaryWriter.Write7BitEncodedInt32(resource.Length); + binaryWriter.Write(resource.HashCode); + binaryWriter.Write7BitEncodedInt32(resource.CompressedLength); + binaryWriter.Write(resource.CompressedHashCode); + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + +#endif + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback.cs.meta new file mode 100644 index 0000000..415e921 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8bff196dc370ba048b548e0be53dc26f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback.cs new file mode 100644 index 0000000..91d05a4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback.cs @@ -0,0 +1,270 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { + /// + /// 反序列化可更新模式版本资源列表(版本 0)回调函数。 + /// + /// 指定流。 + /// 反序列化的可更新模式版本资源列表(版本 0)。 + public static UpdatableVersionList UpdatableVersionListDeserializeCallback_V0(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + string applicableGameVersion = binaryReader.ReadEncryptedString(encryptBytes); + int internalResourceVersion = binaryReader.ReadInt32(); + int assetCount = binaryReader.ReadInt32(); + UpdatableVersionList.Asset[] assets = assetCount > 0 ? new UpdatableVersionList.Asset[assetCount] : null; + int resourceCount = binaryReader.ReadInt32(); + UpdatableVersionList.Resource[] resources = resourceCount > 0 ? new UpdatableVersionList.Resource[resourceCount] : null; + string[][] resourceToAssetNames = new string[resourceCount][]; + List> assetNameToDependencyAssetNames = new List>(assetCount); + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.ReadInt32(); + int hashCode = binaryReader.ReadInt32(); + int compressedLength = binaryReader.ReadInt32(); + int compressedHashCode = binaryReader.ReadInt32(); + Utility.Converter.GetBytes(hashCode, s_CachedHashBytes); + + int assetNameCount = binaryReader.ReadInt32(); + string[] assetNames = assetNameCount > 0 ? new string[assetNameCount] : null; + for (int j = 0; j < assetNameCount; j++) + { + assetNames[j] = binaryReader.ReadEncryptedString(s_CachedHashBytes); + int dependencyAssetNameCount = binaryReader.ReadInt32(); + string[] dependencyAssetNames = dependencyAssetNameCount > 0 ? new string[dependencyAssetNameCount] : null; + for (int k = 0; k < dependencyAssetNameCount; k++) + { + dependencyAssetNames[k] = binaryReader.ReadEncryptedString(s_CachedHashBytes); + } + + assetNameToDependencyAssetNames.Add(new KeyValuePair(assetNames[j], dependencyAssetNames)); + } + + resourceToAssetNames[i] = assetNames; + resources[i] = new UpdatableVersionList.Resource(name, variant, null, loadType, length, hashCode, compressedLength, compressedHashCode, assetNameCount > 0 ? new int[assetNameCount] : null); + } + + assetNameToDependencyAssetNames.Sort(AssetNameToDependencyAssetNamesComparer); + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + int index = 0; + foreach (KeyValuePair i in assetNameToDependencyAssetNames) + { + if (i.Value != null) + { + int[] dependencyAssetIndexes = new int[i.Value.Length]; + for (int j = 0; j < i.Value.Length; j++) + { + dependencyAssetIndexes[j] = GetAssetNameIndex(assetNameToDependencyAssetNames, i.Value[j]); + } + + assets[index++] = new UpdatableVersionList.Asset(i.Key, dependencyAssetIndexes); + } + else + { + assets[index++] = new UpdatableVersionList.Asset(i.Key, null); + } + } + + for (int i = 0; i < resources.Length; i++) + { + int[] assetIndexes = resources[i].GetAssetIndexes(); + for (int j = 0; j < assetIndexes.Length; j++) + { + assetIndexes[j] = GetAssetNameIndex(assetNameToDependencyAssetNames, resourceToAssetNames[i][j]); + } + } + + int resourceGroupCount = binaryReader.ReadInt32(); + UpdatableVersionList.ResourceGroup[] resourceGroups = resourceGroupCount > 0 ? new UpdatableVersionList.ResourceGroup[resourceGroupCount] : null; + for (int i = 0; i < resourceGroupCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.ReadInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.ReadUInt16(); + } + + resourceGroups[i] = new UpdatableVersionList.ResourceGroup(name, resourceIndexes); + } + + return new UpdatableVersionList(applicableGameVersion, internalResourceVersion, assets, resources, null, resourceGroups); + } + } + + /// + /// 反序列化可更新模式版本资源列表(版本 1)回调函数。 + /// + /// 指定流。 + /// 反序列化的可更新模式版本资源列表(版本 1)。 + public static UpdatableVersionList UpdatableVersionListDeserializeCallback_V1(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + string applicableGameVersion = binaryReader.ReadEncryptedString(encryptBytes); + int internalResourceVersion = binaryReader.Read7BitEncodedInt32(); + int assetCount = binaryReader.Read7BitEncodedInt32(); + UpdatableVersionList.Asset[] assets = assetCount > 0 ? new UpdatableVersionList.Asset[assetCount] : null; + for (int i = 0; i < assetCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int dependencyAssetCount = binaryReader.Read7BitEncodedInt32(); + int[] dependencyAssetIndexes = dependencyAssetCount > 0 ? new int[dependencyAssetCount] : null; + for (int j = 0; j < dependencyAssetCount; j++) + { + dependencyAssetIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + assets[i] = new UpdatableVersionList.Asset(name, dependencyAssetIndexes); + } + + int resourceCount = binaryReader.Read7BitEncodedInt32(); + UpdatableVersionList.Resource[] resources = resourceCount > 0 ? new UpdatableVersionList.Resource[resourceCount] : null; + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + string extension = binaryReader.ReadEncryptedString(encryptBytes) ?? DefaultExtension; + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.Read7BitEncodedInt32(); + int hashCode = binaryReader.ReadInt32(); + int compressedLength = binaryReader.Read7BitEncodedInt32(); + int compressedHashCode = binaryReader.ReadInt32(); + int assetIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] assetIndexes = assetIndexCount > 0 ? new int[assetIndexCount] : null; + for (int j = 0; j < assetIndexCount; j++) + { + assetIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + resources[i] = new UpdatableVersionList.Resource(name, variant, extension, loadType, length, hashCode, compressedLength, compressedHashCode, assetIndexes); + } + + int resourceGroupCount = binaryReader.Read7BitEncodedInt32(); + UpdatableVersionList.ResourceGroup[] resourceGroups = resourceGroupCount > 0 ? new UpdatableVersionList.ResourceGroup[resourceGroupCount] : null; + for (int i = 0; i < resourceGroupCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + resourceGroups[i] = new UpdatableVersionList.ResourceGroup(name, resourceIndexes); + } + + return new UpdatableVersionList(applicableGameVersion, internalResourceVersion, assets, resources, null, resourceGroups); + } + } + + /// + /// 反序列化可更新模式版本资源列表(版本 2)回调函数。 + /// + /// 指定流。 + /// 反序列化的可更新模式版本资源列表(版本 2)。 + public static UpdatableVersionList UpdatableVersionListDeserializeCallback_V2(Stream stream) + { + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + byte[] encryptBytes = binaryReader.ReadBytes(CachedHashBytesLength); + string applicableGameVersion = binaryReader.ReadEncryptedString(encryptBytes); + int internalResourceVersion = binaryReader.Read7BitEncodedInt32(); + int assetCount = binaryReader.Read7BitEncodedInt32(); + UpdatableVersionList.Asset[] assets = assetCount > 0 ? new UpdatableVersionList.Asset[assetCount] : null; + for (int i = 0; i < assetCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int dependencyAssetCount = binaryReader.Read7BitEncodedInt32(); + int[] dependencyAssetIndexes = dependencyAssetCount > 0 ? new int[dependencyAssetCount] : null; + for (int j = 0; j < dependencyAssetCount; j++) + { + dependencyAssetIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + assets[i] = new UpdatableVersionList.Asset(name, dependencyAssetIndexes); + } + + int resourceCount = binaryReader.Read7BitEncodedInt32(); + UpdatableVersionList.Resource[] resources = resourceCount > 0 ? new UpdatableVersionList.Resource[resourceCount] : null; + for (int i = 0; i < resourceCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + string variant = binaryReader.ReadEncryptedString(encryptBytes); + string extension = binaryReader.ReadEncryptedString(encryptBytes) ?? DefaultExtension; + byte loadType = binaryReader.ReadByte(); + int length = binaryReader.Read7BitEncodedInt32(); + int hashCode = binaryReader.ReadInt32(); + int compressedLength = binaryReader.Read7BitEncodedInt32(); + int compressedHashCode = binaryReader.ReadInt32(); + int assetIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] assetIndexes = assetIndexCount > 0 ? new int[assetIndexCount] : null; + for (int j = 0; j < assetIndexCount; j++) + { + assetIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + resources[i] = new UpdatableVersionList.Resource(name, variant, extension, loadType, length, hashCode, compressedLength, compressedHashCode, assetIndexes); + } + + int fileSystemCount = binaryReader.Read7BitEncodedInt32(); + UpdatableVersionList.FileSystem[] fileSystems = fileSystemCount > 0 ? new UpdatableVersionList.FileSystem[fileSystemCount] : null; + for (int i = 0; i < fileSystemCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + fileSystems[i] = new UpdatableVersionList.FileSystem(name, resourceIndexes); + } + + int resourceGroupCount = binaryReader.Read7BitEncodedInt32(); + UpdatableVersionList.ResourceGroup[] resourceGroups = resourceGroupCount > 0 ? new UpdatableVersionList.ResourceGroup[resourceGroupCount] : null; + for (int i = 0; i < resourceGroupCount; i++) + { + string name = binaryReader.ReadEncryptedString(encryptBytes); + int resourceIndexCount = binaryReader.Read7BitEncodedInt32(); + int[] resourceIndexes = resourceIndexCount > 0 ? new int[resourceIndexCount] : null; + for (int j = 0; j < resourceIndexCount; j++) + { + resourceIndexes[j] = binaryReader.Read7BitEncodedInt32(); + } + + resourceGroups[i] = new UpdatableVersionList.ResourceGroup(name, resourceIndexes); + } + + return new UpdatableVersionList(applicableGameVersion, internalResourceVersion, assets, resources, fileSystems, resourceGroups); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback.cs.meta new file mode 100644 index 0000000..91ac6ff --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f8075a91786219b4db1b77aa406a81e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback.cs new file mode 100644 index 0000000..bc7782a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback.cs @@ -0,0 +1,245 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +using System; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { +#if UNITY_EDITOR + + /// + /// 序列化可更新模式版本资源列表(版本 0)回调函数。 + /// + /// 目标流。 + /// 要序列化的可更新模式版本资源列表(版本 0)。 + /// 是否序列化可更新模式版本资源列表(版本 0)成功。 + public static bool UpdatableVersionListSerializeCallback_V0(Stream stream, UpdatableVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + binaryWriter.WriteEncryptedString(versionList.ApplicableGameVersion, s_CachedHashBytes); + binaryWriter.Write(versionList.InternalResourceVersion); + UpdatableVersionList.Asset[] assets = versionList.GetAssets(); + binaryWriter.Write(assets.Length); + UpdatableVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write(resources.Length); + foreach (UpdatableVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write(resource.Length); + binaryWriter.Write(resource.HashCode); + binaryWriter.Write(resource.CompressedLength); + binaryWriter.Write(resource.CompressedHashCode); + int[] assetIndexes = resource.GetAssetIndexes(); + binaryWriter.Write(assetIndexes.Length); + byte[] hashBytes = new byte[CachedHashBytesLength]; + foreach (int assetIndex in assetIndexes) + { + Utility.Converter.GetBytes(resource.HashCode, hashBytes); + UpdatableVersionList.Asset asset = assets[assetIndex]; + binaryWriter.WriteEncryptedString(asset.Name, hashBytes); + int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); + binaryWriter.Write(dependencyAssetIndexes.Length); + foreach (int dependencyAssetIndex in dependencyAssetIndexes) + { + binaryWriter.WriteEncryptedString(assets[dependencyAssetIndex].Name, hashBytes); + } + } + } + + UpdatableVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); + binaryWriter.Write(resourceGroups.Length); + foreach (UpdatableVersionList.ResourceGroup resourceGroup in resourceGroups) + { + binaryWriter.WriteEncryptedString(resourceGroup.Name, s_CachedHashBytes); + int[] resourceIndexes = resourceGroup.GetResourceIndexes(); + binaryWriter.Write(resourceIndexes.Length); + foreach (ushort resourceIndex in resourceIndexes) + { + binaryWriter.Write(resourceIndex); + } + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + + /// + /// 序列化可更新模式版本资源列表(版本 1)回调函数。 + /// + /// 目标流。 + /// 要序列化的可更新模式版本资源列表(版本 1)。 + /// 是否序列化可更新模式版本资源列表(版本 1)成功。 + public static bool UpdatableVersionListSerializeCallback_V1(Stream stream, UpdatableVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + binaryWriter.WriteEncryptedString(versionList.ApplicableGameVersion, s_CachedHashBytes); + binaryWriter.Write7BitEncodedInt32(versionList.InternalResourceVersion); + UpdatableVersionList.Asset[] assets = versionList.GetAssets(); + binaryWriter.Write7BitEncodedInt32(assets.Length); + foreach (UpdatableVersionList.Asset asset in assets) + { + binaryWriter.WriteEncryptedString(asset.Name, s_CachedHashBytes); + int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); + binaryWriter.Write7BitEncodedInt32(dependencyAssetIndexes.Length); + foreach (int dependencyAssetIndex in dependencyAssetIndexes) + { + binaryWriter.Write7BitEncodedInt32(dependencyAssetIndex); + } + } + + UpdatableVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write7BitEncodedInt32(resources.Length); + foreach (UpdatableVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Extension != DefaultExtension ? resource.Extension : null, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write7BitEncodedInt32(resource.Length); + binaryWriter.Write(resource.HashCode); + binaryWriter.Write7BitEncodedInt32(resource.CompressedLength); + binaryWriter.Write(resource.CompressedHashCode); + int[] assetIndexes = resource.GetAssetIndexes(); + binaryWriter.Write7BitEncodedInt32(assetIndexes.Length); + foreach (int assetIndex in assetIndexes) + { + binaryWriter.Write7BitEncodedInt32(assetIndex); + } + } + + UpdatableVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); + binaryWriter.Write7BitEncodedInt32(resourceGroups.Length); + foreach (UpdatableVersionList.ResourceGroup resourceGroup in resourceGroups) + { + binaryWriter.WriteEncryptedString(resourceGroup.Name, s_CachedHashBytes); + int[] resourceIndexes = resourceGroup.GetResourceIndexes(); + binaryWriter.Write7BitEncodedInt32(resourceIndexes.Length); + foreach (int resourceIndex in resourceIndexes) + { + binaryWriter.Write7BitEncodedInt32(resourceIndex); + } + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + + /// + /// 序列化可更新模式版本资源列表(版本 2)回调函数。 + /// + /// 目标流。 + /// 要序列化的可更新模式版本资源列表(版本 2)。 + /// 是否序列化可更新模式版本资源列表(版本 2)成功。 + public static bool UpdatableVersionListSerializeCallback_V2(Stream stream, UpdatableVersionList versionList) + { + if (!versionList.IsValid) + { + return false; + } + + Utility.Random.GetRandomBytes(s_CachedHashBytes); + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write(s_CachedHashBytes); + binaryWriter.WriteEncryptedString(versionList.ApplicableGameVersion, s_CachedHashBytes); + binaryWriter.Write7BitEncodedInt32(versionList.InternalResourceVersion); + UpdatableVersionList.Asset[] assets = versionList.GetAssets(); + binaryWriter.Write7BitEncodedInt32(assets.Length); + foreach (UpdatableVersionList.Asset asset in assets) + { + binaryWriter.WriteEncryptedString(asset.Name, s_CachedHashBytes); + int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); + binaryWriter.Write7BitEncodedInt32(dependencyAssetIndexes.Length); + foreach (int dependencyAssetIndex in dependencyAssetIndexes) + { + binaryWriter.Write7BitEncodedInt32(dependencyAssetIndex); + } + } + + UpdatableVersionList.Resource[] resources = versionList.GetResources(); + binaryWriter.Write7BitEncodedInt32(resources.Length); + foreach (UpdatableVersionList.Resource resource in resources) + { + binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); + binaryWriter.WriteEncryptedString(resource.Extension != DefaultExtension ? resource.Extension : null, s_CachedHashBytes); + binaryWriter.Write(resource.LoadType); + binaryWriter.Write7BitEncodedInt32(resource.Length); + binaryWriter.Write(resource.HashCode); + binaryWriter.Write7BitEncodedInt32(resource.CompressedLength); + binaryWriter.Write(resource.CompressedHashCode); + int[] assetIndexes = resource.GetAssetIndexes(); + binaryWriter.Write7BitEncodedInt32(assetIndexes.Length); + foreach (int assetIndex in assetIndexes) + { + binaryWriter.Write7BitEncodedInt32(assetIndex); + } + } + + UpdatableVersionList.FileSystem[] fileSystems = versionList.GetFileSystems(); + binaryWriter.Write7BitEncodedInt32(fileSystems.Length); + foreach (UpdatableVersionList.FileSystem fileSystem in fileSystems) + { + binaryWriter.WriteEncryptedString(fileSystem.Name, s_CachedHashBytes); + int[] resourceIndexes = fileSystem.GetResourceIndexes(); + binaryWriter.Write7BitEncodedInt32(resourceIndexes.Length); + foreach (int resourceIndex in resourceIndexes) + { + binaryWriter.Write7BitEncodedInt32(resourceIndex); + } + } + + UpdatableVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); + binaryWriter.Write7BitEncodedInt32(resourceGroups.Length); + foreach (UpdatableVersionList.ResourceGroup resourceGroup in resourceGroups) + { + binaryWriter.WriteEncryptedString(resourceGroup.Name, s_CachedHashBytes); + int[] resourceIndexes = resourceGroup.GetResourceIndexes(); + binaryWriter.Write7BitEncodedInt32(resourceIndexes.Length); + foreach (int resourceIndex in resourceIndexes) + { + binaryWriter.Write7BitEncodedInt32(resourceIndex); + } + } + } + + Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); + return true; + } + +#endif + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback.cs.meta new file mode 100644 index 0000000..b5a77e7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9730081343813f34e8835804bf32290f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback.cs new file mode 100644 index 0000000..025122c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback.cs @@ -0,0 +1,70 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { + /// + /// 尝试从可更新模式版本资源列表(版本 0)获取指定键的值回调函数。 + /// + /// 指定流。 + /// 指定键。 + /// 指定键的值。 + /// 从可更新模式版本资源列表(版本 0)获取指定键的值是否成功。 + public static bool UpdatableVersionListTryGetValueCallback_V0(Stream stream, string key, out object value) + { + value = null; + if (key != "InternalResourceVersion") + { + return false; + } + + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + binaryReader.BaseStream.Position += CachedHashBytesLength; + byte stringLength = binaryReader.ReadByte(); + binaryReader.BaseStream.Position += stringLength; + value = binaryReader.ReadInt32(); + } + + return true; + } + + /// + /// 尝试从可更新模式版本资源列表(版本 1 或版本 2)获取指定键的值回调函数。 + /// + /// 指定流。 + /// 指定键。 + /// 指定键的值。 + /// 从可更新模式版本资源列表(版本 1 或版本 2)获取指定键的值是否成功。 + public static bool UpdatableVersionListTryGetValueCallback_V1_V2(Stream stream, string key, out object value) + { + value = null; + if (key != "InternalResourceVersion") + { + return false; + } + + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + binaryReader.BaseStream.Position += CachedHashBytesLength; + byte stringLength = binaryReader.ReadByte(); + binaryReader.BaseStream.Position += stringLength; + value = binaryReader.Read7BitEncodedInt32(); + } + + return true; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback.cs.meta new file mode 100644 index 0000000..47c9a4d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c39515b9d8a0b0d4a9045edf9c8c1143 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.cs new file mode 100644 index 0000000..6f9279d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System.Collections.Generic; + +namespace UnityGameFramework.Runtime +{ + /// + /// 内置版本资源列表序列化器。 + /// + public static partial class BuiltinVersionListSerializer + { + private const string DefaultExtension = "dat"; + private const int CachedHashBytesLength = 4; + private static readonly byte[] s_CachedHashBytes = new byte[CachedHashBytesLength]; + + private static int AssetNameToDependencyAssetNamesComparer(KeyValuePair a, KeyValuePair b) + { + return a.Key.CompareTo(b.Key); + } + + private static int GetAssetNameIndex(List> assetNameToDependencyAssetNames, string assetName) + { + return GetAssetNameIndexWithBinarySearch(assetNameToDependencyAssetNames, assetName, 0, assetNameToDependencyAssetNames.Count - 1); + } + + private static int GetAssetNameIndexWithBinarySearch(List> assetNameToDependencyAssetNames, string assetName, int leftIndex, int rightIndex) + { + if (leftIndex > rightIndex) + { + return -1; + } + + int middleIndex = (leftIndex + rightIndex) / 2; + if (assetNameToDependencyAssetNames[middleIndex].Key == assetName) + { + return middleIndex; + } + + if (assetNameToDependencyAssetNames[middleIndex].Key.CompareTo(assetName) > 0) + { + return GetAssetNameIndexWithBinarySearch(assetNameToDependencyAssetNames, assetName, leftIndex, middleIndex - 1); + } + else + { + return GetAssetNameIndexWithBinarySearch(assetNameToDependencyAssetNames, assetName, middleIndex + 1, rightIndex); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.cs.meta new file mode 100644 index 0000000..68a5296 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/BuiltinVersionListSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca9f81a8ced0aa748b1a7a514ccf9948 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultLoadResourceAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultLoadResourceAgentHelper.cs new file mode 100644 index 0000000..4d98e76 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultLoadResourceAgentHelper.cs @@ -0,0 +1,595 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.FileSystem; +using GameFramework.Resource; +using System; +using UnityEngine; +#if UNITY_5_4_OR_NEWER +using UnityEngine.Networking; +#endif +using UnityEngine.SceneManagement; +using Utility = GameFramework.Utility; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认加载资源代理辅助器。 + /// + public class DefaultLoadResourceAgentHelper : LoadResourceAgentHelperBase, IDisposable + { + private string m_FileFullPath = null; + private string m_FileName = null; + private string m_BytesFullPath = null; + private string m_AssetName = null; + private float m_LastProgress = 0f; + private bool m_Disposed = false; +#if UNITY_5_4_OR_NEWER + private UnityWebRequest m_UnityWebRequest = null; +#else + private WWW m_WWW = null; +#endif + private AssetBundleCreateRequest m_FileAssetBundleCreateRequest = null; + private AssetBundleCreateRequest m_BytesAssetBundleCreateRequest = null; + private AssetBundleRequest m_AssetBundleRequest = null; + private AsyncOperation m_AsyncOperation = null; + + private EventHandler m_LoadResourceAgentHelperUpdateEventHandler = null; + private EventHandler m_LoadResourceAgentHelperReadFileCompleteEventHandler = null; + private EventHandler m_LoadResourceAgentHelperReadBytesCompleteEventHandler = null; + private EventHandler m_LoadResourceAgentHelperParseBytesCompleteEventHandler = null; + private EventHandler m_LoadResourceAgentHelperLoadCompleteEventHandler = null; + private EventHandler m_LoadResourceAgentHelperErrorEventHandler = null; + + /// + /// 加载资源代理辅助器异步加载资源更新事件。 + /// + public override event EventHandler LoadResourceAgentHelperUpdate + { + add + { + m_LoadResourceAgentHelperUpdateEventHandler += value; + } + remove + { + m_LoadResourceAgentHelperUpdateEventHandler -= value; + } + } + + /// + /// 加载资源代理辅助器异步读取资源文件完成事件。 + /// + public override event EventHandler LoadResourceAgentHelperReadFileComplete + { + add + { + m_LoadResourceAgentHelperReadFileCompleteEventHandler += value; + } + remove + { + m_LoadResourceAgentHelperReadFileCompleteEventHandler -= value; + } + } + + /// + /// 加载资源代理辅助器异步读取资源二进制流完成事件。 + /// + public override event EventHandler LoadResourceAgentHelperReadBytesComplete + { + add + { + m_LoadResourceAgentHelperReadBytesCompleteEventHandler += value; + } + remove + { + m_LoadResourceAgentHelperReadBytesCompleteEventHandler -= value; + } + } + + /// + /// 加载资源代理辅助器异步将资源二进制流转换为加载对象完成事件。 + /// + public override event EventHandler LoadResourceAgentHelperParseBytesComplete + { + add + { + m_LoadResourceAgentHelperParseBytesCompleteEventHandler += value; + } + remove + { + m_LoadResourceAgentHelperParseBytesCompleteEventHandler -= value; + } + } + + /// + /// 加载资源代理辅助器异步加载资源完成事件。 + /// + public override event EventHandler LoadResourceAgentHelperLoadComplete + { + add + { + m_LoadResourceAgentHelperLoadCompleteEventHandler += value; + } + remove + { + m_LoadResourceAgentHelperLoadCompleteEventHandler -= value; + } + } + + /// + /// 加载资源代理辅助器错误事件。 + /// + public override event EventHandler LoadResourceAgentHelperError + { + add + { + m_LoadResourceAgentHelperErrorEventHandler += value; + } + remove + { + m_LoadResourceAgentHelperErrorEventHandler -= value; + } + } + + /// + /// 通过加载资源代理辅助器开始异步读取资源文件。 + /// + /// 要加载资源的完整路径名。 + public override void ReadFile(string fullPath) + { + if (m_LoadResourceAgentHelperReadFileCompleteEventHandler == null || m_LoadResourceAgentHelperUpdateEventHandler == null || m_LoadResourceAgentHelperErrorEventHandler == null) + { + Log.Fatal("Load resource agent helper handler is invalid."); + return; + } + + m_FileFullPath = fullPath; + m_FileAssetBundleCreateRequest = AssetBundle.LoadFromFileAsync(fullPath); + } + + /// + /// 通过加载资源代理辅助器开始异步读取资源文件。 + /// + /// 要加载资源的文件系统。 + /// 要加载资源的名称。 + public override void ReadFile(IFileSystem fileSystem, string name) + { +#if UNITY_5_3_5 || UNITY_5_3_6 || UNITY_5_3_7 || UNITY_5_3_8 || UNITY_5_4_OR_NEWER + if (m_LoadResourceAgentHelperReadFileCompleteEventHandler == null || m_LoadResourceAgentHelperUpdateEventHandler == null || m_LoadResourceAgentHelperErrorEventHandler == null) + { + Log.Fatal("Load resource agent helper handler is invalid."); + return; + } + + FileInfo fileInfo = fileSystem.GetFileInfo(name); + m_FileFullPath = fileSystem.FullPath; + m_FileName = name; + m_FileAssetBundleCreateRequest = AssetBundle.LoadFromFileAsync(fileSystem.FullPath, 0u, (ulong)fileInfo.Offset); +#else + Log.Fatal("Load from file async with offset is not supported, use Unity 5.3.5f1 or above."); +#endif + } + + /// + /// 通过加载资源代理辅助器开始异步读取资源二进制流。 + /// + /// 要加载资源的完整路径名。 + public override void ReadBytes(string fullPath) + { + if (m_LoadResourceAgentHelperReadBytesCompleteEventHandler == null || m_LoadResourceAgentHelperUpdateEventHandler == null || m_LoadResourceAgentHelperErrorEventHandler == null) + { + Log.Fatal("Load resource agent helper handler is invalid."); + return; + } + + m_BytesFullPath = fullPath; +#if UNITY_5_4_OR_NEWER + m_UnityWebRequest = UnityWebRequest.Get(Utility.Path.GetRemotePath(fullPath)); +#if UNITY_2017_2_OR_NEWER + m_UnityWebRequest.SendWebRequest(); +#else + m_UnityWebRequest.Send(); +#endif +#else + m_WWW = new WWW(Utility.Path.GetRemotePath(fullPath)); +#endif + } + + /// + /// 通过加载资源代理辅助器开始异步读取资源二进制流。 + /// + /// 要加载资源的文件系统。 + /// 要加载资源的名称。 + public override void ReadBytes(IFileSystem fileSystem, string name) + { + if (m_LoadResourceAgentHelperReadBytesCompleteEventHandler == null || m_LoadResourceAgentHelperUpdateEventHandler == null || m_LoadResourceAgentHelperErrorEventHandler == null) + { + Log.Fatal("Load resource agent helper handler is invalid."); + return; + } + + byte[] bytes = fileSystem.ReadFile(name); + LoadResourceAgentHelperReadBytesCompleteEventArgs loadResourceAgentHelperReadBytesCompleteEventArgs = LoadResourceAgentHelperReadBytesCompleteEventArgs.Create(bytes); + m_LoadResourceAgentHelperReadBytesCompleteEventHandler(this, loadResourceAgentHelperReadBytesCompleteEventArgs); + ReferencePool.Release(loadResourceAgentHelperReadBytesCompleteEventArgs); + } + + /// + /// 通过加载资源代理辅助器开始异步将资源二进制流转换为加载对象。 + /// + /// 要加载资源的二进制流。 + public override void ParseBytes(byte[] bytes) + { + if (m_LoadResourceAgentHelperParseBytesCompleteEventHandler == null || m_LoadResourceAgentHelperUpdateEventHandler == null || m_LoadResourceAgentHelperErrorEventHandler == null) + { + Log.Fatal("Load resource agent helper handler is invalid."); + return; + } + + m_BytesAssetBundleCreateRequest = AssetBundle.LoadFromMemoryAsync(bytes); + } + + /// + /// 通过加载资源代理辅助器开始异步加载资源。 + /// + /// 资源。 + /// 要加载的资源名称。 + /// 要加载资源的类型。 + /// 要加载的资源是否是场景。 + public override void LoadAsset(object resource, string assetName, Type assetType, bool isScene) + { + if (m_LoadResourceAgentHelperLoadCompleteEventHandler == null || m_LoadResourceAgentHelperUpdateEventHandler == null || m_LoadResourceAgentHelperErrorEventHandler == null) + { + Log.Fatal("Load resource agent helper handler is invalid."); + return; + } + + AssetBundle assetBundle = resource as AssetBundle; + if (assetBundle == null) + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.TypeError, "Can not load asset bundle from loaded resource which is not an asset bundle."); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + return; + } + + if (string.IsNullOrEmpty(assetName)) + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.AssetError, "Can not load asset from asset bundle which child name is invalid."); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + return; + } + + m_AssetName = assetName; + if (isScene) + { + int sceneNamePositionStart = assetName.LastIndexOf('/'); + int sceneNamePositionEnd = assetName.LastIndexOf('.'); + if (sceneNamePositionStart <= 0 || sceneNamePositionEnd <= 0 || sceneNamePositionStart > sceneNamePositionEnd) + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.AssetError, Utility.Text.Format("Scene name '{0}' is invalid.", assetName)); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + return; + } + + string sceneName = assetName.Substring(sceneNamePositionStart + 1, sceneNamePositionEnd - sceneNamePositionStart - 1); + m_AsyncOperation = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive); + } + else + { + if (assetType != null) + { + m_AssetBundleRequest = assetBundle.LoadAssetAsync(assetName, assetType); + } + else + { + m_AssetBundleRequest = assetBundle.LoadAssetAsync(assetName); + } + } + } + + /// + /// 重置加载资源代理辅助器。 + /// + public override void Reset() + { + m_FileFullPath = null; + m_FileName = null; + m_BytesFullPath = null; + m_AssetName = null; + m_LastProgress = 0f; + +#if UNITY_5_4_OR_NEWER + if (m_UnityWebRequest != null) + { + m_UnityWebRequest.Dispose(); + m_UnityWebRequest = null; + } +#else + if (m_WWW != null) + { + m_WWW.Dispose(); + m_WWW = null; + } +#endif + + m_FileAssetBundleCreateRequest = null; + m_BytesAssetBundleCreateRequest = null; + m_AssetBundleRequest = null; + m_AsyncOperation = null; + } + + /// + /// 释放资源。 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 释放资源。 + /// + /// 释放资源标记。 + protected virtual void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { +#if UNITY_5_4_OR_NEWER + if (m_UnityWebRequest != null) + { + m_UnityWebRequest.Dispose(); + m_UnityWebRequest = null; + } +#else + if (m_WWW != null) + { + m_WWW.Dispose(); + m_WWW = null; + } +#endif + } + + m_Disposed = true; + } + + private void Update() + { +#if UNITY_5_4_OR_NEWER + UpdateUnityWebRequest(); +#else + UpdateWWW(); +#endif + UpdateFileAssetBundleCreateRequest(); + UpdateBytesAssetBundleCreateRequest(); + UpdateAssetBundleRequest(); + UpdateAsyncOperation(); + } + +#if UNITY_5_4_OR_NEWER + private void UpdateUnityWebRequest() + { + if (m_UnityWebRequest != null) + { + if (m_UnityWebRequest.isDone) + { + if (string.IsNullOrEmpty(m_UnityWebRequest.error)) + { + LoadResourceAgentHelperReadBytesCompleteEventArgs loadResourceAgentHelperReadBytesCompleteEventArgs = LoadResourceAgentHelperReadBytesCompleteEventArgs.Create(m_UnityWebRequest.downloadHandler.data); + m_LoadResourceAgentHelperReadBytesCompleteEventHandler(this, loadResourceAgentHelperReadBytesCompleteEventArgs); + ReferencePool.Release(loadResourceAgentHelperReadBytesCompleteEventArgs); + m_UnityWebRequest.Dispose(); + m_UnityWebRequest = null; + m_BytesFullPath = null; + m_LastProgress = 0f; + } + else + { + bool isError = false; +#if UNITY_2020_2_OR_NEWER + isError = m_UnityWebRequest.result != UnityWebRequest.Result.Success; +#elif UNITY_2017_1_OR_NEWER + isError = m_UnityWebRequest.isNetworkError || m_UnityWebRequest.isHttpError; +#else + isError = m_UnityWebRequest.isError; +#endif + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.NotExist, Utility.Text.Format("Can not load asset bundle '{0}' with error message '{1}'.", m_BytesFullPath, isError ? m_UnityWebRequest.error : null)); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + } + } + else if (m_UnityWebRequest.downloadProgress != m_LastProgress) + { + m_LastProgress = m_UnityWebRequest.downloadProgress; + LoadResourceAgentHelperUpdateEventArgs loadResourceAgentHelperUpdateEventArgs = LoadResourceAgentHelperUpdateEventArgs.Create(LoadResourceProgress.ReadResource, m_UnityWebRequest.downloadProgress); + m_LoadResourceAgentHelperUpdateEventHandler(this, loadResourceAgentHelperUpdateEventArgs); + ReferencePool.Release(loadResourceAgentHelperUpdateEventArgs); + } + } + } +#else + private void UpdateWWW() + { + if (m_WWW != null) + { + if (m_WWW.isDone) + { + if (string.IsNullOrEmpty(m_WWW.error)) + { + LoadResourceAgentHelperReadBytesCompleteEventArgs loadResourceAgentHelperReadBytesCompleteEventArgs = LoadResourceAgentHelperReadBytesCompleteEventArgs.Create(m_WWW.bytes); + m_LoadResourceAgentHelperReadBytesCompleteEventHandler(this, loadResourceAgentHelperReadBytesCompleteEventArgs); + ReferencePool.Release(loadResourceAgentHelperReadBytesCompleteEventArgs); + m_WWW.Dispose(); + m_WWW = null; + m_BytesFullPath = null; + m_LastProgress = 0f; + } + else + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.NotExist, Utility.Text.Format("Can not load asset bundle '{0}' with error message '{1}'.", m_BytesFullPath, m_WWW.error)); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + } + } + else if (m_WWW.progress != m_LastProgress) + { + m_LastProgress = m_WWW.progress; + LoadResourceAgentHelperUpdateEventArgs loadResourceAgentHelperUpdateEventArgs = LoadResourceAgentHelperUpdateEventArgs.Create(LoadResourceProgress.ReadResource, m_WWW.progress); + m_LoadResourceAgentHelperUpdateEventHandler(this, loadResourceAgentHelperUpdateEventArgs); + ReferencePool.Release(loadResourceAgentHelperUpdateEventArgs); + } + } + } +#endif + + private void UpdateFileAssetBundleCreateRequest() + { + if (m_FileAssetBundleCreateRequest != null) + { + if (m_FileAssetBundleCreateRequest.isDone) + { + AssetBundle assetBundle = m_FileAssetBundleCreateRequest.assetBundle; + if (assetBundle != null) + { + AssetBundleCreateRequest oldFileAssetBundleCreateRequest = m_FileAssetBundleCreateRequest; + LoadResourceAgentHelperReadFileCompleteEventArgs loadResourceAgentHelperReadFileCompleteEventArgs = LoadResourceAgentHelperReadFileCompleteEventArgs.Create(assetBundle); + m_LoadResourceAgentHelperReadFileCompleteEventHandler(this, loadResourceAgentHelperReadFileCompleteEventArgs); + ReferencePool.Release(loadResourceAgentHelperReadFileCompleteEventArgs); + if (m_FileAssetBundleCreateRequest == oldFileAssetBundleCreateRequest) + { + m_FileAssetBundleCreateRequest = null; + m_LastProgress = 0f; + } + } + else + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.NotExist, Utility.Text.Format("Can not load asset bundle from file '{0}' which is not a valid asset bundle.", m_FileName == null ? m_FileFullPath : Utility.Text.Format("{0} | {1}", m_FileFullPath, m_FileName))); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + } + } + else if (m_FileAssetBundleCreateRequest.progress != m_LastProgress) + { + m_LastProgress = m_FileAssetBundleCreateRequest.progress; + LoadResourceAgentHelperUpdateEventArgs loadResourceAgentHelperUpdateEventArgs = LoadResourceAgentHelperUpdateEventArgs.Create(LoadResourceProgress.LoadResource, m_FileAssetBundleCreateRequest.progress); + m_LoadResourceAgentHelperUpdateEventHandler(this, loadResourceAgentHelperUpdateEventArgs); + ReferencePool.Release(loadResourceAgentHelperUpdateEventArgs); + } + } + } + + private void UpdateBytesAssetBundleCreateRequest() + { + if (m_BytesAssetBundleCreateRequest != null) + { + if (m_BytesAssetBundleCreateRequest.isDone) + { + AssetBundle assetBundle = m_BytesAssetBundleCreateRequest.assetBundle; + if (assetBundle != null) + { + AssetBundleCreateRequest oldBytesAssetBundleCreateRequest = m_BytesAssetBundleCreateRequest; + LoadResourceAgentHelperParseBytesCompleteEventArgs loadResourceAgentHelperParseBytesCompleteEventArgs = LoadResourceAgentHelperParseBytesCompleteEventArgs.Create(assetBundle); + m_LoadResourceAgentHelperParseBytesCompleteEventHandler(this, loadResourceAgentHelperParseBytesCompleteEventArgs); + ReferencePool.Release(loadResourceAgentHelperParseBytesCompleteEventArgs); + if (m_BytesAssetBundleCreateRequest == oldBytesAssetBundleCreateRequest) + { + m_BytesAssetBundleCreateRequest = null; + m_LastProgress = 0f; + } + } + else + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.NotExist, "Can not load asset bundle from memory which is not a valid asset bundle."); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + } + } + else if (m_BytesAssetBundleCreateRequest.progress != m_LastProgress) + { + m_LastProgress = m_BytesAssetBundleCreateRequest.progress; + LoadResourceAgentHelperUpdateEventArgs loadResourceAgentHelperUpdateEventArgs = LoadResourceAgentHelperUpdateEventArgs.Create(LoadResourceProgress.LoadResource, m_BytesAssetBundleCreateRequest.progress); + m_LoadResourceAgentHelperUpdateEventHandler(this, loadResourceAgentHelperUpdateEventArgs); + ReferencePool.Release(loadResourceAgentHelperUpdateEventArgs); + } + } + } + + private void UpdateAssetBundleRequest() + { + if (m_AssetBundleRequest != null) + { + if (m_AssetBundleRequest.isDone) + { + if (m_AssetBundleRequest.asset != null) + { + LoadResourceAgentHelperLoadCompleteEventArgs loadResourceAgentHelperLoadCompleteEventArgs = LoadResourceAgentHelperLoadCompleteEventArgs.Create(m_AssetBundleRequest.asset); + m_LoadResourceAgentHelperLoadCompleteEventHandler(this, loadResourceAgentHelperLoadCompleteEventArgs); + ReferencePool.Release(loadResourceAgentHelperLoadCompleteEventArgs); + m_AssetName = null; + m_LastProgress = 0f; + m_AssetBundleRequest = null; + } + else + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.AssetError, Utility.Text.Format("Can not load asset '{0}' from asset bundle which is not exist.", m_AssetName)); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + } + } + else if (m_AssetBundleRequest.progress != m_LastProgress) + { + m_LastProgress = m_AssetBundleRequest.progress; + LoadResourceAgentHelperUpdateEventArgs loadResourceAgentHelperUpdateEventArgs = LoadResourceAgentHelperUpdateEventArgs.Create(LoadResourceProgress.LoadAsset, m_AssetBundleRequest.progress); + m_LoadResourceAgentHelperUpdateEventHandler(this, loadResourceAgentHelperUpdateEventArgs); + ReferencePool.Release(loadResourceAgentHelperUpdateEventArgs); + } + } + } + + private void UpdateAsyncOperation() + { + if (m_AsyncOperation != null) + { + if (m_AsyncOperation.isDone) + { + if (m_AsyncOperation.allowSceneActivation) + { + SceneAsset sceneAsset = new SceneAsset(); + LoadResourceAgentHelperLoadCompleteEventArgs loadResourceAgentHelperLoadCompleteEventArgs = LoadResourceAgentHelperLoadCompleteEventArgs.Create(sceneAsset); + m_LoadResourceAgentHelperLoadCompleteEventHandler(this, loadResourceAgentHelperLoadCompleteEventArgs); + ReferencePool.Release(loadResourceAgentHelperLoadCompleteEventArgs); + m_AssetName = null; + m_LastProgress = 0f; + m_AsyncOperation = null; + } + else + { + LoadResourceAgentHelperErrorEventArgs loadResourceAgentHelperErrorEventArgs = LoadResourceAgentHelperErrorEventArgs.Create(LoadResourceStatus.AssetError, Utility.Text.Format("Can not load scene asset '{0}' from asset bundle.", m_AssetName)); + m_LoadResourceAgentHelperErrorEventHandler(this, loadResourceAgentHelperErrorEventArgs); + ReferencePool.Release(loadResourceAgentHelperErrorEventArgs); + } + } + else if (m_AsyncOperation.progress != m_LastProgress) + { + m_LastProgress = m_AsyncOperation.progress; + LoadResourceAgentHelperUpdateEventArgs loadResourceAgentHelperUpdateEventArgs = LoadResourceAgentHelperUpdateEventArgs.Create(LoadResourceProgress.LoadScene, m_AsyncOperation.progress); + m_LoadResourceAgentHelperUpdateEventHandler(this, loadResourceAgentHelperUpdateEventArgs); + ReferencePool.Release(loadResourceAgentHelperUpdateEventArgs); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultLoadResourceAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultLoadResourceAgentHelper.cs.meta new file mode 100644 index 0000000..91c066e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultLoadResourceAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9288c544ad6d5a84d8e3610015bc5d61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultResourceHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultResourceHelper.cs new file mode 100644 index 0000000..e90f950 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultResourceHelper.cs @@ -0,0 +1,185 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using System; +using System.Collections; +using UnityEngine; +#if UNITY_5_4_OR_NEWER +using UnityEngine.Networking; +#endif +using UnityEngine.SceneManagement; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认资源辅助器。 + /// + public class DefaultResourceHelper : ResourceHelperBase + { + /// + /// 直接从指定文件路径加载数据流。 + /// + /// 文件路径。 + /// 加载数据流回调函数集。 + /// 用户自定义数据。 + public override void LoadBytes(string fileUri, LoadBytesCallbacks loadBytesCallbacks, object userData) + { + StartCoroutine(LoadBytesCo(fileUri, loadBytesCallbacks, userData)); + } + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + /// 卸载场景回调函数集。 + /// 用户自定义数据。 + public override void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData) + { +#if UNITY_5_5_OR_NEWER + if (gameObject.activeInHierarchy) + { + StartCoroutine(UnloadSceneCo(sceneAssetName, unloadSceneCallbacks, userData)); + } + else + { + SceneManager.UnloadSceneAsync(SceneComponent.GetSceneName(sceneAssetName)); + } +#else + if (SceneManager.UnloadScene(SceneComponent.GetSceneName(sceneAssetName))) + { + if (unloadSceneCallbacks.UnloadSceneSuccessCallback != null) + { + unloadSceneCallbacks.UnloadSceneSuccessCallback(sceneAssetName, userData); + } + } + else + { + if (unloadSceneCallbacks.UnloadSceneFailureCallback != null) + { + unloadSceneCallbacks.UnloadSceneFailureCallback(sceneAssetName, userData); + } + } +#endif + } + + /// + /// 释放资源。 + /// + /// 要释放的资源。 + public override void Release(object objectToRelease) + { + AssetBundle assetBundle = objectToRelease as AssetBundle; + if (assetBundle != null) + { + assetBundle.Unload(true); + return; + } + + /* Unity 当前 Resources.UnloadAsset 在 iOS 设备上会导致一些诡异问题,先不用这部分 + SceneAsset sceneAsset = objectToRelease as SceneAsset; + if (sceneAsset != null) + { + return; + } + + Object unityObject = objectToRelease as Object; + if (unityObject == null) + { + Log.Warning("Asset is invalid."); + return; + } + + if (unityObject is GameObject || unityObject is MonoBehaviour) + { + // UnloadAsset may only be used on individual assets and can not be used on GameObject's / Components or AssetBundles. + return; + } + + Resources.UnloadAsset(unityObject); + */ + } + + private void Start() + { + } + + private IEnumerator LoadBytesCo(string fileUri, LoadBytesCallbacks loadBytesCallbacks, object userData) + { + bool isError = false; + byte[] bytes = null; + string errorMessage = null; + DateTime startTime = DateTime.UtcNow; + +#if UNITY_5_4_OR_NEWER + UnityWebRequest unityWebRequest = UnityWebRequest.Get(fileUri); +#if UNITY_2017_2_OR_NEWER + yield return unityWebRequest.SendWebRequest(); +#else + yield return unityWebRequest.Send(); +#endif + +#if UNITY_2020_2_OR_NEWER + isError = unityWebRequest.result != UnityWebRequest.Result.Success; +#elif UNITY_2017_1_OR_NEWER + isError = unityWebRequest.isNetworkError || unityWebRequest.isHttpError; +#else + isError = unityWebRequest.isError; +#endif + bytes = unityWebRequest.downloadHandler.data; + errorMessage = isError ? unityWebRequest.error : null; + unityWebRequest.Dispose(); +#else + WWW www = new WWW(fileUri); + yield return www; + + isError = !string.IsNullOrEmpty(www.error); + bytes = www.bytes; + errorMessage = www.error; + www.Dispose(); +#endif + + if (!isError) + { + float elapseSeconds = (float)(DateTime.UtcNow - startTime).TotalSeconds; + loadBytesCallbacks.LoadBytesSuccessCallback(fileUri, bytes, elapseSeconds, userData); + } + else if (loadBytesCallbacks.LoadBytesFailureCallback != null) + { + loadBytesCallbacks.LoadBytesFailureCallback(fileUri, errorMessage, userData); + } + } + +#if UNITY_5_5_OR_NEWER + private IEnumerator UnloadSceneCo(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData) + { + AsyncOperation asyncOperation = SceneManager.UnloadSceneAsync(SceneComponent.GetSceneName(sceneAssetName)); + if (asyncOperation == null) + { + yield break; + } + + yield return asyncOperation; + + if (asyncOperation.allowSceneActivation) + { + if (unloadSceneCallbacks.UnloadSceneSuccessCallback != null) + { + unloadSceneCallbacks.UnloadSceneSuccessCallback(sceneAssetName, userData); + } + } + else + { + if (unloadSceneCallbacks.UnloadSceneFailureCallback != null) + { + unloadSceneCallbacks.UnloadSceneFailureCallback(sceneAssetName, userData); + } + } + } +#endif + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultResourceHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultResourceHelper.cs.meta new file mode 100644 index 0000000..0cbaefd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/DefaultResourceHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 720e532446c14964a8fe343f1196793f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/EditorResourceComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/EditorResourceComponent.cs new file mode 100644 index 0000000..019115e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/EditorResourceComponent.cs @@ -0,0 +1,1867 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Download; +using GameFramework.FileSystem; +using GameFramework.ObjectPool; +using GameFramework.Resource; +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace UnityGameFramework.Runtime +{ + /// + /// 编辑器资源组件。 + /// + [DisallowMultipleComponent] + public sealed class EditorResourceComponent : MonoBehaviour, IResourceManager + { + private const int DefaultPriority = 0; + private static readonly int AssetsStringLength = "Assets".Length; + + [SerializeField] + private bool m_EnableCachedAssets = true; + + [SerializeField] + private int m_LoadAssetCountPerFrame = 1; + + [SerializeField] + private float m_MinLoadAssetRandomDelaySeconds = 0f; + + [SerializeField] + private float m_MaxLoadAssetRandomDelaySeconds = 0f; + + private string m_ReadOnlyPath = null; + private string m_ReadWritePath = null; + private Dictionary m_CachedAssets = null; + private GameFrameworkLinkedList m_LoadAssetInfos = null; + private GameFrameworkLinkedList m_LoadSceneInfos = null; + private GameFrameworkLinkedList m_UnloadSceneInfos = null; + + /// + /// 获取资源只读区路径。 + /// + public string ReadOnlyPath + { + get + { + return m_ReadOnlyPath; + } + } + + /// + /// 获取资源读写区路径。 + /// + public string ReadWritePath + { + get + { + return m_ReadWritePath; + } + } + + /// + /// 获取资源模式。 + /// + public ResourceMode ResourceMode + { + get + { + return ResourceMode.Unspecified; + } + } + + /// + /// 获取当前变体。 + /// + public string CurrentVariant + { + get + { + return null; + } + } + + /// + /// 获取单机模式版本资源列表序列化器。 + /// + public PackageVersionListSerializer PackageVersionListSerializer + { + get + { + throw new NotSupportedException("ReadWriteVersionListSerializer"); + } + } + + /// + /// 获取可更新模式版本资源列表序列化器。 + /// + public UpdatableVersionListSerializer UpdatableVersionListSerializer + { + get + { + throw new NotSupportedException("ReadWriteVersionListSerializer"); + } + } + + /// + /// 获取本地只读区版本资源列表序列化器。 + /// + public ReadOnlyVersionListSerializer ReadOnlyVersionListSerializer + { + get + { + throw new NotSupportedException("ReadWriteVersionListSerializer"); + } + } + + /// + /// 获取本地读写区版本资源列表序列化器。 + /// + public ReadWriteVersionListSerializer ReadWriteVersionListSerializer + { + get + { + throw new NotSupportedException("ReadWriteVersionListSerializer"); + } + } + + /// + /// 获取资源包版本资源列表序列化器。 + /// + public ResourcePackVersionListSerializer ResourcePackVersionListSerializer + { + get + { + throw new NotSupportedException("ResourcePackVersionListSerializer"); + } + } + + /// + /// 获取当前资源适用的游戏版本号。 + /// + public string ApplicableGameVersion + { + get + { + throw new NotSupportedException("ApplicableGameVersion"); + } + } + + /// + /// 获取当前内部资源版本号。 + /// + public int InternalResourceVersion + { + get + { + throw new NotSupportedException("InternalResourceVersion"); + } + } + + /// + /// 获取已准备完毕资源数量。 + /// + public int AssetCount + { + get + { + throw new NotSupportedException("AssetCount"); + } + } + + /// + /// 获取已准备完毕资源数量。 + /// + public int ResourceCount + { + get + { + throw new NotSupportedException("ResourceCount"); + } + } + + /// + /// 获取资源组个数。 + /// + public int ResourceGroupCount + { + get + { + throw new NotSupportedException("ResourceGroupCount"); + } + } + + /// + /// 获取或设置资源更新下载地址。 + /// + public string UpdatePrefixUri + { + get + { + throw new NotSupportedException("UpdatePrefixUri"); + } + set + { + throw new NotSupportedException("UpdatePrefixUri"); + } + } + + /// + /// 获取或设置每更新多少字节的资源,重新生成一次版本资源列表。 + /// + public int GenerateReadWriteVersionListLength + { + get + { + throw new NotSupportedException("GenerateReadWriteVersionListLength"); + } + set + { + throw new NotSupportedException("GenerateReadWriteVersionListLength"); + } + } + + /// + /// 获取正在应用的资源包路径。 + /// + public string ApplyingResourcePackPath + { + get + { + throw new NotSupportedException("ApplyingResourcePackPath"); + } + } + + /// + /// 获取等待应用资源数量。 + /// + public int ApplyWaitingCount + { + get + { + throw new NotSupportedException("ApplyWaitingCount"); + } + } + + /// + /// 获取或设置资源更新重试次数。 + /// + public int UpdateRetryCount + { + get + { + throw new NotSupportedException("UpdateRetryCount"); + } + set + { + throw new NotSupportedException("UpdateRetryCount"); + } + } + + /// + /// 获取正在更新的资源组。 + /// + public IResourceGroup UpdatingResourceGroup + { + get + { + throw new NotSupportedException("UpdatingResourceGroup"); + } + } + + /// + /// 获取等待更新资源个数。 + /// + public int UpdateWaitingCount + { + get + { + throw new NotSupportedException("UpdateWaitingCount"); + } + } + + /// + /// 获取使用时下载的等待更新资源数量。 + /// + public int UpdateWaitingWhilePlayingCount + { + get + { + throw new NotSupportedException("UpdateWaitingWhilePlayingCount"); + } + } + + /// + /// 获取候选更新资源数量。 + /// + public int UpdateCandidateCount + { + get + { + throw new NotSupportedException("UpdateCandidateCount"); + } + } + + /// + /// 获取加载资源代理总个数。 + /// + public int LoadTotalAgentCount + { + get + { + throw new NotSupportedException("LoadTotalAgentCount"); + } + } + + /// + /// 获取可用加载资源代理个数。 + /// + public int LoadFreeAgentCount + { + get + { + throw new NotSupportedException("LoadFreeAgentCount"); + } + } + + /// + /// 获取工作中加载资源代理个数。 + /// + public int LoadWorkingAgentCount + { + get + { + throw new NotSupportedException("LoadWorkingAgentCount"); + } + } + + /// + /// 获取等待加载资源任务个数。 + /// + public int LoadWaitingTaskCount + { + get + { + throw new NotSupportedException("LoadWaitingTaskCount"); + } + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + public float AssetAutoReleaseInterval + { + get + { + throw new NotSupportedException("AssetAutoReleaseInterval"); + } + set + { + throw new NotSupportedException("AssetAutoReleaseInterval"); + } + } + + /// + /// 获取或设置资源对象池的容量。 + /// + public int AssetCapacity + { + get + { + throw new NotSupportedException("AssetCapacity"); + } + set + { + throw new NotSupportedException("AssetCapacity"); + } + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + public float AssetExpireTime + { + get + { + throw new NotSupportedException("AssetExpireTime"); + } + set + { + throw new NotSupportedException("AssetExpireTime"); + } + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + public int AssetPriority + { + get + { + throw new NotSupportedException("AssetPriority"); + } + set + { + throw new NotSupportedException("AssetPriority"); + } + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + public float ResourceAutoReleaseInterval + { + get + { + throw new NotSupportedException("ResourceAutoReleaseInterval"); + } + set + { + throw new NotSupportedException("ResourceAutoReleaseInterval"); + } + } + + /// + /// 获取或设置资源对象池的容量。 + /// + public int ResourceCapacity + { + get + { + throw new NotSupportedException("ResourceCapacity"); + } + set + { + throw new NotSupportedException("ResourceCapacity"); + } + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + public float ResourceExpireTime + { + get + { + throw new NotSupportedException("ResourceExpireTime"); + } + set + { + throw new NotSupportedException("ResourceExpireTime"); + } + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + public int ResourcePriority + { + get + { + throw new NotSupportedException("ResourcePriority"); + } + set + { + throw new NotSupportedException("ResourcePriority"); + } + } + + /// + /// 获取等待编辑器加载的资源数量。 + /// + public int LoadWaitingAssetCount + { + get + { + return m_LoadAssetInfos.Count; + } + } + +#pragma warning disable 0067, 0414 + + /// + /// 资源校验开始事件。 + /// + public event EventHandler ResourceVerifyStart = null; + + /// + /// 资源校验成功事件。 + /// + public event EventHandler ResourceVerifySuccess = null; + + /// + /// 资源校验失败事件。 + /// + public event EventHandler ResourceVerifyFailure = null; + + /// + /// 资源应用开始事件。 + /// + public event EventHandler ResourceApplyStart = null; + + /// + /// 资源应用成功事件。 + /// + public event EventHandler ResourceApplySuccess = null; + + /// + /// 资源应用失败事件。 + /// + public event EventHandler ResourceApplyFailure = null; + + /// + /// 资源更新开始事件。 + /// + public event EventHandler ResourceUpdateStart = null; + + /// + /// 资源更新改变事件。 + /// + public event EventHandler ResourceUpdateChanged = null; + + /// + /// 资源更新成功事件。 + /// + public event EventHandler ResourceUpdateSuccess = null; + + /// + /// 资源更新失败事件。 + /// + public event EventHandler ResourceUpdateFailure = null; + + /// + /// 资源更新全部完成事件。 + /// + public event EventHandler ResourceUpdateAllComplete = null; + +#pragma warning restore 0067, 0414 + + private void Awake() + { + m_ReadOnlyPath = null; + m_ReadWritePath = null; + m_CachedAssets = new Dictionary(StringComparer.Ordinal); + m_LoadAssetInfos = new GameFrameworkLinkedList(); + m_LoadSceneInfos = new GameFrameworkLinkedList(); + m_UnloadSceneInfos = new GameFrameworkLinkedList(); + + BaseComponent baseComponent = GetComponent(); + if (baseComponent == null) + { + Log.Error("Can not find base component."); + return; + } + + if (baseComponent.EditorResourceMode) + { + baseComponent.EditorResourceHelper = this; + enabled = true; + } + else + { + enabled = false; + } + } + + private void Update() + { + if (m_LoadAssetInfos.Count > 0) + { + int count = 0; + LinkedListNode current = m_LoadAssetInfos.First; + while (current != null && count < m_LoadAssetCountPerFrame) + { + LoadAssetInfo loadAssetInfo = current.Value; + float elapseSeconds = (float)(DateTime.UtcNow - loadAssetInfo.StartTime).TotalSeconds; + if (elapseSeconds >= loadAssetInfo.DelaySeconds) + { + UnityEngine.Object asset = GetCachedAsset(loadAssetInfo.AssetName); + if (asset == null) + { +#if UNITY_EDITOR + if (loadAssetInfo.AssetType != null) + { + asset = UnityEditor.AssetDatabase.LoadAssetAtPath(loadAssetInfo.AssetName, loadAssetInfo.AssetType); + } + else + { + asset = UnityEditor.AssetDatabase.LoadMainAssetAtPath(loadAssetInfo.AssetName); + } + + if (m_EnableCachedAssets && asset != null) + { + m_CachedAssets.Add(loadAssetInfo.AssetName, asset); + } +#endif + } + + if (asset != null) + { + if (loadAssetInfo.LoadAssetCallbacks.LoadAssetSuccessCallback != null) + { + loadAssetInfo.LoadAssetCallbacks.LoadAssetSuccessCallback(loadAssetInfo.AssetName, asset, elapseSeconds, loadAssetInfo.UserData); + } + } + else + { + if (loadAssetInfo.LoadAssetCallbacks.LoadAssetFailureCallback != null) + { + loadAssetInfo.LoadAssetCallbacks.LoadAssetFailureCallback(loadAssetInfo.AssetName, LoadResourceStatus.AssetError, "Can not load this asset from asset database.", loadAssetInfo.UserData); + } + } + + LinkedListNode next = current.Next; + m_LoadAssetInfos.Remove(loadAssetInfo); + current = next; + count++; + } + else + { + if (loadAssetInfo.LoadAssetCallbacks.LoadAssetUpdateCallback != null) + { + loadAssetInfo.LoadAssetCallbacks.LoadAssetUpdateCallback(loadAssetInfo.AssetName, elapseSeconds / loadAssetInfo.DelaySeconds, loadAssetInfo.UserData); + } + + current = current.Next; + } + } + } + + if (m_LoadSceneInfos.Count > 0) + { + LinkedListNode current = m_LoadSceneInfos.First; + while (current != null) + { + LoadSceneInfo loadSceneInfo = current.Value; + if (loadSceneInfo.AsyncOperation.isDone) + { + if (loadSceneInfo.AsyncOperation.allowSceneActivation) + { + if (loadSceneInfo.LoadSceneCallbacks.LoadSceneSuccessCallback != null) + { + loadSceneInfo.LoadSceneCallbacks.LoadSceneSuccessCallback(loadSceneInfo.SceneAssetName, (float)(DateTime.UtcNow - loadSceneInfo.StartTime).TotalSeconds, loadSceneInfo.UserData); + } + } + else + { + if (loadSceneInfo.LoadSceneCallbacks.LoadSceneFailureCallback != null) + { + loadSceneInfo.LoadSceneCallbacks.LoadSceneFailureCallback(loadSceneInfo.SceneAssetName, LoadResourceStatus.AssetError, "Can not load this scene from asset database.", loadSceneInfo.UserData); + } + } + + LinkedListNode next = current.Next; + m_LoadSceneInfos.Remove(loadSceneInfo); + current = next; + } + else + { + if (loadSceneInfo.LoadSceneCallbacks.LoadSceneUpdateCallback != null) + { + loadSceneInfo.LoadSceneCallbacks.LoadSceneUpdateCallback(loadSceneInfo.SceneAssetName, loadSceneInfo.AsyncOperation.progress, loadSceneInfo.UserData); + } + + current = current.Next; + } + } + } + + if (m_UnloadSceneInfos.Count > 0) + { + LinkedListNode current = m_UnloadSceneInfos.First; + while (current != null) + { + UnloadSceneInfo unloadSceneInfo = current.Value; + if (unloadSceneInfo.AsyncOperation.isDone) + { + if (unloadSceneInfo.AsyncOperation.allowSceneActivation) + { + if (unloadSceneInfo.UnloadSceneCallbacks.UnloadSceneSuccessCallback != null) + { + unloadSceneInfo.UnloadSceneCallbacks.UnloadSceneSuccessCallback(unloadSceneInfo.SceneAssetName, unloadSceneInfo.UserData); + } + } + else + { + if (unloadSceneInfo.UnloadSceneCallbacks.UnloadSceneFailureCallback != null) + { + unloadSceneInfo.UnloadSceneCallbacks.UnloadSceneFailureCallback(unloadSceneInfo.SceneAssetName, unloadSceneInfo.UserData); + } + } + + LinkedListNode next = current.Next; + m_UnloadSceneInfos.Remove(unloadSceneInfo); + current = next; + } + else + { + current = current.Next; + } + } + } + } + + /// + /// 设置资源只读区路径。 + /// + /// 资源只读区路径。 + public void SetReadOnlyPath(string readOnlyPath) + { + if (string.IsNullOrEmpty(readOnlyPath)) + { + Log.Error("Read-only path is invalid."); + return; + } + + m_ReadOnlyPath = readOnlyPath; + } + + /// + /// 设置资源读写区路径。 + /// + /// 资源读写区路径。 + public void SetReadWritePath(string readWritePath) + { + if (string.IsNullOrEmpty(readWritePath)) + { + Log.Error("Read-write path is invalid."); + return; + } + + m_ReadWritePath = readWritePath; + } + + /// + /// 设置资源模式。 + /// + /// 资源模式。 + public void SetResourceMode(ResourceMode resourceMode) + { + throw new NotSupportedException("SetResourceMode"); + } + + /// + /// 设置当前变体。 + /// + /// 当前变体。 + public void SetCurrentVariant(string currentVariant) + { + throw new NotSupportedException("SetCurrentVariant"); + } + + /// + /// 设置对象池管理器。 + /// + /// 对象池管理器。 + public void SetObjectPoolManager(IObjectPoolManager objectPoolManager) + { + throw new NotSupportedException("SetObjectPoolManager"); + } + + /// + /// 设置文件系统管理器。 + /// + /// 文件系统管理器。 + public void SetFileSystemManager(IFileSystemManager fileSystemManager) + { + throw new NotSupportedException("SetFileSystemManager"); + } + + /// + /// 设置下载管理器。 + /// + /// 下载管理器。 + public void SetDownloadManager(IDownloadManager downloadManager) + { + throw new NotSupportedException("SetDownloadManager"); + } + + /// + /// 设置解密资源回调函数。 + /// + /// 要设置的解密资源回调函数。 + /// 如果不设置,将使用默认的解密资源回调函数。 + public void SetDecryptResourceCallback(DecryptResourceCallback decryptResourceCallback) + { + throw new NotSupportedException("SetDecryptResourceCallback"); + } + + /// + /// 设置资源辅助器。 + /// + /// 资源辅助器。 + public void SetResourceHelper(IResourceHelper resourceHelper) + { + throw new NotSupportedException("SetResourceHelper"); + } + + /// + /// 增加加载资源代理辅助器。 + /// + /// 要增加的加载资源代理辅助器。 + public void AddLoadResourceAgentHelper(ILoadResourceAgentHelper loadResourceAgentHelper) + { + throw new NotSupportedException("AddLoadResourceAgentHelper"); + } + + /// + /// 使用单机模式并初始化资源。 + /// + /// 使用单机模式并初始化资源完成时的回调函数。 + public void InitResources(InitResourcesCompleteCallback initResourcesCompleteCallback) + { + throw new NotSupportedException("InitResources"); + } + + /// + /// 检查版本资源列表。 + /// + /// 最新的内部资源版本号。 + /// 检查版本资源列表结果。 + public CheckVersionListResult CheckVersionList(int latestInternalResourceVersion) + { + throw new NotSupportedException("CheckVersionList"); + } + + /// + /// 使用可更新模式并更新版本资源列表。 + /// + /// 版本资源列表大小。 + /// 版本资源列表哈希值。 + /// 版本资源列表压缩后大小。 + /// 版本资源列表压缩后哈希值。 + /// 版本资源列表更新回调函数集。 + public void UpdateVersionList(int versionListLength, int versionListHashCode, int versionListCompressedLength, int versionListCompressedHashCode, UpdateVersionListCallbacks updateVersionListCallbacks) + { + throw new NotSupportedException("UpdateVersionList"); + } + + /// + /// 使用可更新模式并校验资源。 + /// + /// 每帧至少校验资源的大小,以字节为单位。 + /// 使用可更新模式并校验资源完成时的回调函数。 + public void VerifyResources(int verifyResourceLengthPerFrame, VerifyResourcesCompleteCallback verifyResourcesCompleteCallback) + { + throw new NotSupportedException("VerifyResources"); + } + + /// + /// 使用可更新模式并检查资源。 + /// + /// 是否忽略处理其它变体的资源,若不忽略,将会移除其它变体的资源。 + /// 使用可更新模式并检查资源完成时的回调函数。 + public void CheckResources(bool ignoreOtherVariant, CheckResourcesCompleteCallback checkResourcesCompleteCallback) + { + throw new NotSupportedException("CheckResources"); + } + + /// + /// 使用可更新模式并应用资源包资源。 + /// + /// 要应用的资源包路径。 + /// 使用可更新模式并应用资源包资源完成时的回调函数。 + public void ApplyResources(string resourcePackPath, ApplyResourcesCompleteCallback applyResourcesCompleteCallback) + { + throw new NotSupportedException("ApplyResources"); + } + + /// + /// 使用可更新模式并更新所有资源。 + /// + /// 使用可更新模式并更新默认资源组完成时的回调函数。 + public void UpdateResources(UpdateResourcesCompleteCallback updateResourcesCompleteCallback) + { + throw new NotSupportedException("UpdateResources"); + } + + /// + /// 使用可更新模式并更新指定资源组的资源。 + /// + /// 要更新的资源组名称。 + /// 使用可更新模式并更新指定资源组完成时的回调函数。 + public void UpdateResources(string resourceGroupName, UpdateResourcesCompleteCallback updateResourcesCompleteCallback) + { + throw new NotSupportedException("UpdateResources"); + } + + /// + /// 停止更新资源。 + /// + public void StopUpdateResources() + { + throw new NotSupportedException("StopUpdateResources"); + } + + /// + /// 校验资源包。 + /// + /// 要校验的资源包路径。 + /// 是否校验资源包成功。 + public bool VerifyResourcePack(string resourcePackPath) + { + throw new NotSupportedException("VerifyResourcePack"); + } + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + public TaskInfo[] GetAllLoadAssetInfos() + { + throw new NotSupportedException("GetAllLoadAssetInfos"); + } + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + public void GetAllLoadAssetInfos(List results) + { + throw new NotSupportedException("GetAllLoadAssetInfos"); + } + + /// + /// 检查资源是否存在。 + /// + /// 要检查资源的名称。 + /// 检查资源是否存在的结果。 + public HasAssetResult HasAsset(string assetName) + { +#if UNITY_EDITOR + UnityEngine.Object obj = UnityEditor.AssetDatabase.LoadMainAssetAtPath(assetName); + if (obj == null) + { + return HasAssetResult.NotExist; + } + + HasAssetResult result = obj.GetType() == typeof(UnityEditor.DefaultAsset) ? HasAssetResult.BinaryOnDisk : HasAssetResult.AssetOnDisk; + obj = null; + UnityEditor.EditorUtility.UnloadUnusedAssetsImmediate(); + return result; +#else + return HasAssetResult.NotExist; +#endif + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks) + { + LoadAsset(assetName, null, DefaultPriority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, Type assetType, LoadAssetCallbacks loadAssetCallbacks) + { + LoadAsset(assetName, assetType, DefaultPriority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, int priority, LoadAssetCallbacks loadAssetCallbacks) + { + LoadAsset(assetName, null, priority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + LoadAsset(assetName, null, DefaultPriority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks) + { + LoadAsset(assetName, assetType, priority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, Type assetType, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + LoadAsset(assetName, assetType, DefaultPriority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + LoadAsset(assetName, null, priority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + if (loadAssetCallbacks == null) + { + Log.Error("Load asset callbacks is invalid."); + return; + } + + if (string.IsNullOrEmpty(assetName)) + { + if (loadAssetCallbacks.LoadAssetFailureCallback != null) + { + loadAssetCallbacks.LoadAssetFailureCallback(assetName, LoadResourceStatus.NotExist, "Asset name is invalid.", userData); + } + + return; + } + + if (!assetName.StartsWith("Assets/", StringComparison.Ordinal)) + { + if (loadAssetCallbacks.LoadAssetFailureCallback != null) + { + loadAssetCallbacks.LoadAssetFailureCallback(assetName, LoadResourceStatus.NotExist, Utility.Text.Format("Asset name '{0}' is invalid.", assetName), userData); + } + + return; + } + + if (!HasFile(assetName)) + { + if (loadAssetCallbacks.LoadAssetFailureCallback != null) + { + loadAssetCallbacks.LoadAssetFailureCallback(assetName, LoadResourceStatus.NotExist, Utility.Text.Format("Asset '{0}' is not exist.", assetName), userData); + } + + return; + } + + m_LoadAssetInfos.AddLast(new LoadAssetInfo(assetName, assetType, priority, DateTime.UtcNow, m_MinLoadAssetRandomDelaySeconds + (float)Utility.Random.GetRandomDouble() * (m_MaxLoadAssetRandomDelaySeconds - m_MinLoadAssetRandomDelaySeconds), loadAssetCallbacks, userData)); + } + + /// + /// 卸载资源。 + /// + /// 要卸载的资源。 + public void UnloadAsset(object asset) + { + // Do nothing in editor resource mode. + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景回调函数集。 + public void LoadScene(string sceneAssetName, LoadSceneCallbacks loadSceneCallbacks) + { + LoadScene(sceneAssetName, DefaultPriority, loadSceneCallbacks, null); + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景资源的优先级。 + /// 加载场景回调函数集。 + public void LoadScene(string sceneAssetName, int priority, LoadSceneCallbacks loadSceneCallbacks) + { + LoadScene(sceneAssetName, priority, loadSceneCallbacks, null); + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景回调函数集。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, LoadSceneCallbacks loadSceneCallbacks, object userData) + { + LoadScene(sceneAssetName, DefaultPriority, loadSceneCallbacks, userData); + } + + /// + /// 异步加载场景。 + /// + /// 要加载场景资源的名称。 + /// 加载场景资源的优先级。 + /// 加载场景回调函数集。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, int priority, LoadSceneCallbacks loadSceneCallbacks, object userData) + { + if (loadSceneCallbacks == null) + { + Log.Error("Load scene callbacks is invalid."); + return; + } + + if (string.IsNullOrEmpty(sceneAssetName)) + { + if (loadSceneCallbacks.LoadSceneFailureCallback != null) + { + loadSceneCallbacks.LoadSceneFailureCallback(sceneAssetName, LoadResourceStatus.NotExist, "Scene asset name is invalid.", userData); + } + + return; + } + + if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) + { + if (loadSceneCallbacks.LoadSceneFailureCallback != null) + { + loadSceneCallbacks.LoadSceneFailureCallback(sceneAssetName, LoadResourceStatus.NotExist, Utility.Text.Format("Scene asset name '{0}' is invalid.", sceneAssetName), userData); + } + + return; + } + + if (!HasFile(sceneAssetName)) + { + if (loadSceneCallbacks.LoadSceneFailureCallback != null) + { + loadSceneCallbacks.LoadSceneFailureCallback(sceneAssetName, LoadResourceStatus.NotExist, Utility.Text.Format("Scene '{0}' is not exist.", sceneAssetName), userData); + } + + return; + } + +#if UNITY_5_5_OR_NEWER + AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneAssetName, LoadSceneMode.Additive); +#else + AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(SceneComponent.GetSceneName(sceneAssetName), LoadSceneMode.Additive); +#endif + if (asyncOperation == null) + { + return; + } + + m_LoadSceneInfos.AddLast(new LoadSceneInfo(asyncOperation, sceneAssetName, priority, DateTime.UtcNow, loadSceneCallbacks, userData)); + } + + /// + /// 异步卸载场景。 + /// + /// 要卸载场景资源的名称。 + /// 卸载场景回调函数集。 + public void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks) + { + UnloadScene(sceneAssetName, unloadSceneCallbacks, null); + } + + /// + /// 异步卸载场景。 + /// + /// 要卸载场景资源的名称。 + /// 卸载场景回调函数集。 + /// 用户自定义数据。 + public void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + Log.Error("Scene asset name is invalid."); + return; + } + + if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) + { + Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); + return; + } + + if (unloadSceneCallbacks == null) + { + Log.Error("Unload scene callbacks is invalid."); + return; + } + + if (!HasFile(sceneAssetName)) + { + Log.Error("Scene '{0}' is not exist.", sceneAssetName); + return; + } + +#if UNITY_5_5_OR_NEWER + AsyncOperation asyncOperation = SceneManager.UnloadSceneAsync(sceneAssetName); + if (asyncOperation == null) + { + return; + } + + m_UnloadSceneInfos.AddLast(new UnloadSceneInfo(asyncOperation, sceneAssetName, unloadSceneCallbacks, userData)); +#else + if (SceneManager.UnloadScene(SceneComponent.GetSceneName(sceneAssetName))) + { + if (unloadSceneCallbacks.UnloadSceneSuccessCallback != null) + { + unloadSceneCallbacks.UnloadSceneSuccessCallback(sceneAssetName, userData); + } + } + else + { + if (unloadSceneCallbacks.UnloadSceneFailureCallback != null) + { + unloadSceneCallbacks.UnloadSceneFailureCallback(sceneAssetName, userData); + } + } +#endif + } + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源的实际路径。 + /// 此方法仅适用于二进制资源存储在磁盘(而非文件系统)中的情况。若二进制资源存储在文件系统中时,返回值将始终为空。 + public string GetBinaryPath(string binaryAssetName) + { + if (!HasFile(binaryAssetName)) + { + return null; + } + + return Application.dataPath.Substring(0, Application.dataPath.Length - AssetsStringLength) + binaryAssetName; + } + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源是否存储在只读区中。 + /// 二进制资源是否存储在文件系统中。 + /// 二进制资源或存储二进制资源的文件系统,相对于只读区或者读写区的相对路径。 + /// 若二进制资源存储在文件系统中,则指示二进制资源在文件系统中的名称,否则此参数返回空。 + /// 是否获取二进制资源的实际路径成功。 + public bool GetBinaryPath(string binaryAssetName, out bool storageInReadOnly, out bool storageInFileSystem, out string relativePath, out string fileName) + { + throw new NotSupportedException("GetBinaryPath"); + } + + /// + /// 获取二进制资源的长度。 + /// + /// 要获取长度的二进制资源的名称。 + /// 二进制资源的长度。 + public int GetBinaryLength(string binaryAssetName) + { + string binaryPath = GetBinaryPath(binaryAssetName); + if (string.IsNullOrEmpty(binaryPath)) + { + return -1; + } + + return (int)new System.IO.FileInfo(binaryPath).Length; + } + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + public void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks) + { + LoadBinary(binaryAssetName, loadBinaryCallbacks, null); + } + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + /// 用户自定义数据。 + public void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks, object userData) + { + if (loadBinaryCallbacks == null) + { + Log.Error("Load binary callbacks is invalid."); + return; + } + + if (string.IsNullOrEmpty(binaryAssetName)) + { + if (loadBinaryCallbacks.LoadBinaryFailureCallback != null) + { + loadBinaryCallbacks.LoadBinaryFailureCallback(binaryAssetName, LoadResourceStatus.NotExist, "Binary asset name is invalid.", userData); + } + + return; + } + + if (!binaryAssetName.StartsWith("Assets/", StringComparison.Ordinal)) + { + if (loadBinaryCallbacks.LoadBinaryFailureCallback != null) + { + loadBinaryCallbacks.LoadBinaryFailureCallback(binaryAssetName, LoadResourceStatus.NotExist, Utility.Text.Format("Binary asset name '{0}' is invalid.", binaryAssetName), userData); + } + + return; + } + + string binaryPath = GetBinaryPath(binaryAssetName); + if (binaryPath == null) + { + if (loadBinaryCallbacks.LoadBinaryFailureCallback != null) + { + loadBinaryCallbacks.LoadBinaryFailureCallback(binaryAssetName, LoadResourceStatus.NotExist, Utility.Text.Format("Binary asset '{0}' is not exist.", binaryAssetName), userData); + } + + return; + } + + try + { + byte[] binaryBytes = File.ReadAllBytes(binaryPath); + loadBinaryCallbacks.LoadBinarySuccessCallback(binaryAssetName, binaryBytes, 0f, userData); + } + catch (Exception exception) + { + if (loadBinaryCallbacks.LoadBinaryFailureCallback != null) + { + loadBinaryCallbacks.LoadBinaryFailureCallback(binaryAssetName, LoadResourceStatus.AssetError, exception.ToString(), userData); + } + } + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + public byte[] LoadBinaryFromFileSystem(string binaryAssetName) + { + throw new NotSupportedException("LoadBinaryFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer) + { + throw new NotSupportedException("LoadBinaryFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex) + { + throw new NotSupportedException("LoadBinaryFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 存储加载二进制资源的二进制流的长度。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length) + { + throw new NotSupportedException("LoadBinaryFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + public byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int length) + { + throw new NotSupportedException("LoadBinarySegmentFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + public byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, int length) + { + throw new NotSupportedException("LoadBinarySegmentFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer) + { + throw new NotSupportedException("LoadBinarySegmentFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer, int length) + { + throw new NotSupportedException("LoadBinarySegmentFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length) + { + throw new NotSupportedException("LoadBinarySegmentFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer) + { + throw new NotSupportedException("LoadBinarySegmentFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int length) + { + throw new NotSupportedException("LoadBinarySegmentFromFileSystem"); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int startIndex, int length) + { + throw new NotSupportedException("LoadBinarySegmentFromFileSystem"); + } + + /// + /// 检查资源组是否存在。 + /// + /// 要检查资源组的名称。 + /// 资源组是否存在。 + public bool HasResourceGroup(string resourceGroupName) + { + throw new NotSupportedException("HasResourceGroup"); + } + + /// + /// 获取默认资源组。 + /// + /// 默认资源组。 + public IResourceGroup GetResourceGroup() + { + throw new NotSupportedException("GetResourceGroup"); + } + + /// + /// 获取资源组。 + /// + /// 要获取的资源组名称。 + /// 要获取的资源组。 + public IResourceGroup GetResourceGroup(string resourceGroupName) + { + throw new NotSupportedException("GetResourceGroup"); + } + + /// + /// 获取所有资源组。 + /// + /// 所有资源组。 + public IResourceGroup[] GetAllResourceGroups() + { + throw new NotSupportedException("GetAllResourceGroups"); + } + + /// + /// 获取所有资源组。 + /// + /// 所有资源组。 + public void GetAllResourceGroups(List results) + { + throw new NotSupportedException("GetAllResourceGroups"); + } + + /// + /// 获取资源组集合。 + /// + /// 要获取的资源组名称的集合。 + /// 要获取的资源组集合。 + public IResourceGroupCollection GetResourceGroupCollection(params string[] resourceGroupNames) + { + throw new NotSupportedException("GetResourceGroupCollection"); + } + + /// + /// 获取资源组集合。 + /// + /// 要获取的资源组名称的集合。 + /// 要获取的资源组集合。 + public IResourceGroupCollection GetResourceGroupCollection(List resourceGroupNames) + { + throw new NotSupportedException("GetResourceGroupCollection"); + } + + private bool HasFile(string assetName) + { + if (string.IsNullOrEmpty(assetName)) + { + return false; + } + + if (HasCachedAsset(assetName)) + { + return true; + } + + string assetFullName = Application.dataPath.Substring(0, Application.dataPath.Length - AssetsStringLength) + assetName; + if (string.IsNullOrEmpty(assetFullName)) + { + return false; + } + + string[] splitedAssetFullName = assetFullName.Split('/'); + string currentPath = Path.GetPathRoot(assetFullName); + for (int i = 1; i < splitedAssetFullName.Length - 1; i++) + { + string[] directoryNames = Directory.GetDirectories(currentPath, splitedAssetFullName[i]); + if (directoryNames.Length != 1) + { + return false; + } + + currentPath = directoryNames[0]; + } + + string[] fileNames = Directory.GetFiles(currentPath, splitedAssetFullName[splitedAssetFullName.Length - 1]); + if (fileNames.Length != 1) + { + return false; + } + + string fileFullName = Utility.Path.GetRegularPath(fileNames[0]); + if (fileFullName == null) + { + return false; + } + + if (assetFullName != fileFullName) + { + if (assetFullName.ToLowerInvariant() == fileFullName.ToLowerInvariant()) + { + Log.Warning("The real path of the specific asset '{0}' is '{1}'. Check the case of letters in the path.", assetName, "Assets" + fileFullName.Substring(Application.dataPath.Length)); + } + + return false; + } + + return true; + } + + private bool HasCachedAsset(string assetName) + { + if (!m_EnableCachedAssets) + { + return false; + } + + if (string.IsNullOrEmpty(assetName)) + { + return false; + } + + return m_CachedAssets.ContainsKey(assetName); + } + + private UnityEngine.Object GetCachedAsset(string assetName) + { + if (!m_EnableCachedAssets) + { + return null; + } + + if (string.IsNullOrEmpty(assetName)) + { + return null; + } + + UnityEngine.Object asset = null; + if (m_CachedAssets.TryGetValue(assetName, out asset)) + { + return asset; + } + + return null; + } + + [StructLayout(LayoutKind.Auto)] + private struct LoadAssetInfo + { + private readonly string m_AssetName; + private readonly Type m_AssetType; + private readonly int m_Priority; + private readonly DateTime m_StartTime; + private readonly float m_DelaySeconds; + private readonly LoadAssetCallbacks m_LoadAssetCallbacks; + private readonly object m_UserData; + + public LoadAssetInfo(string assetName, Type assetType, int priority, DateTime startTime, float delaySeconds, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + m_AssetName = assetName; + m_AssetType = assetType; + m_Priority = priority; + m_StartTime = startTime; + m_DelaySeconds = delaySeconds; + m_LoadAssetCallbacks = loadAssetCallbacks; + m_UserData = userData; + } + + public string AssetName + { + get + { + return m_AssetName; + } + } + + public Type AssetType + { + get + { + return m_AssetType; + } + } + + public int Priority + { + get + { + return m_Priority; + } + } + + public DateTime StartTime + { + get + { + return m_StartTime; + } + } + + public float DelaySeconds + { + get + { + return m_DelaySeconds; + } + } + + public LoadAssetCallbacks LoadAssetCallbacks + { + get + { + return m_LoadAssetCallbacks; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + } + + [StructLayout(LayoutKind.Auto)] + private struct LoadSceneInfo + { + private readonly AsyncOperation m_AsyncOperation; + private readonly string m_SceneAssetName; + private readonly int m_Priority; + private readonly DateTime m_StartTime; + private readonly LoadSceneCallbacks m_LoadSceneCallbacks; + private readonly object m_UserData; + + public LoadSceneInfo(AsyncOperation asyncOperation, string sceneAssetName, int priority, DateTime startTime, LoadSceneCallbacks loadSceneCallbacks, object userData) + { + m_AsyncOperation = asyncOperation; + m_SceneAssetName = sceneAssetName; + m_Priority = priority; + m_StartTime = startTime; + m_LoadSceneCallbacks = loadSceneCallbacks; + m_UserData = userData; + } + + public AsyncOperation AsyncOperation + { + get + { + return m_AsyncOperation; + } + } + + public string SceneAssetName + { + get + { + return m_SceneAssetName; + } + } + + public int Priority + { + get + { + return m_Priority; + } + } + + public DateTime StartTime + { + get + { + return m_StartTime; + } + } + + public LoadSceneCallbacks LoadSceneCallbacks + { + get + { + return m_LoadSceneCallbacks; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + } + + [StructLayout(LayoutKind.Auto)] + private struct UnloadSceneInfo + { + private readonly AsyncOperation m_AsyncOperation; + private readonly string m_SceneAssetName; + private readonly UnloadSceneCallbacks m_UnloadSceneCallbacks; + private readonly object m_UserData; + + public UnloadSceneInfo(AsyncOperation asyncOperation, string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData) + { + m_AsyncOperation = asyncOperation; + m_SceneAssetName = sceneAssetName; + m_UnloadSceneCallbacks = unloadSceneCallbacks; + m_UserData = userData; + } + + public AsyncOperation AsyncOperation + { + get + { + return m_AsyncOperation; + } + } + + public string SceneAssetName + { + get + { + return m_SceneAssetName; + } + } + + public UnloadSceneCallbacks UnloadSceneCallbacks + { + get + { + return m_UnloadSceneCallbacks; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/EditorResourceComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/EditorResourceComponent.cs.meta new file mode 100644 index 0000000..9d5df4b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/EditorResourceComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c26ec20b78ec32048bfb6c0ff875d8cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/LoadResourceAgentHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/LoadResourceAgentHelperBase.cs new file mode 100644 index 0000000..2a7d788 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/LoadResourceAgentHelperBase.cs @@ -0,0 +1,96 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.FileSystem; +using GameFramework.Resource; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载资源代理辅助器基类。 + /// + public abstract class LoadResourceAgentHelperBase : MonoBehaviour, ILoadResourceAgentHelper + { + /// + /// 加载资源代理辅助器异步加载资源更新事件。 + /// + public abstract event EventHandler LoadResourceAgentHelperUpdate; + + /// + /// 加载资源代理辅助器异步读取资源文件完成事件。 + /// + public abstract event EventHandler LoadResourceAgentHelperReadFileComplete; + + /// + /// 加载资源代理辅助器异步读取资源二进制流完成事件。 + /// + public abstract event EventHandler LoadResourceAgentHelperReadBytesComplete; + + /// + /// 加载资源代理辅助器异步将资源二进制流转换为加载对象完成事件。 + /// + public abstract event EventHandler LoadResourceAgentHelperParseBytesComplete; + + /// + /// 加载资源代理辅助器异步加载资源完成事件。 + /// + public abstract event EventHandler LoadResourceAgentHelperLoadComplete; + + /// + /// 加载资源代理辅助器错误事件。 + /// + public abstract event EventHandler LoadResourceAgentHelperError; + + /// + /// 通过加载资源代理辅助器开始异步读取资源文件。 + /// + /// 要加载资源的完整路径名。 + public abstract void ReadFile(string fullPath); + + /// + /// 通过加载资源代理辅助器开始异步读取资源文件。 + /// + /// 要加载资源的文件系统。 + /// 要加载资源的名称。 + public abstract void ReadFile(IFileSystem fileSystem, string name); + + /// + /// 通过加载资源代理辅助器开始异步读取资源二进制流。 + /// + /// 要加载资源的完整路径名。 + public abstract void ReadBytes(string fullPath); + + /// + /// 通过加载资源代理辅助器开始异步读取资源二进制流。 + /// + /// 要加载资源的文件系统。 + /// 要加载资源的名称。 + public abstract void ReadBytes(IFileSystem fileSystem, string name); + + /// + /// 通过加载资源代理辅助器开始异步将资源二进制流转换为加载对象。 + /// + /// 要加载资源的二进制流。 + public abstract void ParseBytes(byte[] bytes); + + /// + /// 通过加载资源代理辅助器开始异步加载资源。 + /// + /// 资源。 + /// 要加载的资源名称。 + /// 要加载资源的类型。 + /// 要加载的资源是否是场景。 + public abstract void LoadAsset(object resource, string assetName, Type assetType, bool isScene); + + /// + /// 重置加载资源代理辅助器。 + /// + public abstract void Reset(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/LoadResourceAgentHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/LoadResourceAgentHelperBase.cs.meta new file mode 100644 index 0000000..8a8bfa0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/LoadResourceAgentHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 753d0ffbb600b8a4888c18a954ca0985 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ReadWritePathType.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ReadWritePathType.cs new file mode 100644 index 0000000..5f41bf4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ReadWritePathType.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + /// + /// 读写区路径类型。 + /// + public enum ReadWritePathType : byte + { + /// + /// 未指定。 + /// + Unspecified = 0, + + /// + /// 临时缓存。 + /// + TemporaryCache, + + /// + /// 持久化数据。 + /// + PersistentData, + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ReadWritePathType.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ReadWritePathType.cs.meta new file mode 100644 index 0000000..d88efcd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ReadWritePathType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59125eb0ef72f9a4cbe2fd08f0876ed7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyFailureEventArgs.cs new file mode 100644 index 0000000..1052e48 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyFailureEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源应用失败事件。 + /// + public sealed class ResourceApplyFailureEventArgs : GameEventArgs + { + /// + /// 资源应用失败事件编号。 + /// + public static readonly int EventId = typeof(ResourceApplyFailureEventArgs).GetHashCode(); + + /// + /// 初始化资源应用失败事件的新实例。 + /// + public ResourceApplyFailureEventArgs() + { + Name = null; + ResourcePackPath = null; + ErrorMessage = null; + } + + /// + /// 获取资源应用失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源包路径。 + /// + public string ResourcePackPath + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建资源应用失败事件。 + /// + /// 内部事件。 + /// 创建的资源应用失败事件。 + public static ResourceApplyFailureEventArgs Create(GameFramework.Resource.ResourceApplyFailureEventArgs e) + { + ResourceApplyFailureEventArgs resourceApplyFailureEventArgs = ReferencePool.Acquire(); + resourceApplyFailureEventArgs.Name = e.Name; + resourceApplyFailureEventArgs.ResourcePackPath = e.ResourcePackPath; + resourceApplyFailureEventArgs.ErrorMessage = e.ErrorMessage; + return resourceApplyFailureEventArgs; + } + + /// + /// 清理资源应用失败事件。 + /// + public override void Clear() + { + Name = null; + ResourcePackPath = null; + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyFailureEventArgs.cs.meta new file mode 100644 index 0000000..d51598d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 66fd3ef74ebb3c64a85b92714b6fca9f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyStartEventArgs.cs new file mode 100644 index 0000000..3d8775b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyStartEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源应用开始事件。 + /// + public sealed class ResourceApplyStartEventArgs : GameEventArgs + { + /// + /// 资源应用开始事件编号。 + /// + public static readonly int EventId = typeof(ResourceApplyStartEventArgs).GetHashCode(); + + /// + /// 初始化资源应用开始事件的新实例。 + /// + public ResourceApplyStartEventArgs() + { + ResourcePackPath = null; + Count = 0; + TotalLength = 0L; + } + + /// + /// 获取资源应用开始事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源包路径。 + /// + public string ResourcePackPath + { + get; + private set; + } + + /// + /// 获取要应用资源的数量。 + /// + public int Count + { + get; + private set; + } + + /// + /// 获取要应用资源的总大小。 + /// + public long TotalLength + { + get; + private set; + } + + /// + /// 创建资源应用开始事件。 + /// + /// 内部事件。 + /// 创建的资源应用开始事件。 + public static ResourceApplyStartEventArgs Create(GameFramework.Resource.ResourceApplyStartEventArgs e) + { + ResourceApplyStartEventArgs resourceApplyStartEventArgs = ReferencePool.Acquire(); + resourceApplyStartEventArgs.ResourcePackPath = e.ResourcePackPath; + resourceApplyStartEventArgs.Count = e.Count; + resourceApplyStartEventArgs.TotalLength = e.TotalLength; + return resourceApplyStartEventArgs; + } + + /// + /// 清理资源应用开始事件。 + /// + public override void Clear() + { + ResourcePackPath = null; + Count = 0; + TotalLength = 0L; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyStartEventArgs.cs.meta new file mode 100644 index 0000000..3dad449 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplyStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2b8dac8903914b4b90a288cb8ad3d06 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplySuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplySuccessEventArgs.cs new file mode 100644 index 0000000..858d046 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplySuccessEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源应用成功事件。 + /// + public sealed class ResourceApplySuccessEventArgs : GameEventArgs + { + /// + /// 资源应用成功事件编号。 + /// + public static readonly int EventId = typeof(ResourceApplySuccessEventArgs).GetHashCode(); + + /// + /// 初始化资源应用成功事件的新实例。 + /// + public ResourceApplySuccessEventArgs() + { + Name = null; + ApplyPath = null; + ResourcePackPath = null; + Length = 0; + CompressedLength = 0; + } + + /// + /// 获取资源应用成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源应用后存放路径。 + /// + public string ApplyPath + { + get; + private set; + } + + /// + /// 获取资源包路径。 + /// + public string ResourcePackPath + { + get; + private set; + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get; + private set; + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get; + private set; + } + + /// + /// 创建资源应用成功事件。 + /// + /// 内部事件。 + /// 创建的资源应用成功事件。 + public static ResourceApplySuccessEventArgs Create(GameFramework.Resource.ResourceApplySuccessEventArgs e) + { + ResourceApplySuccessEventArgs resourceApplySuccessEventArgs = ReferencePool.Acquire(); + resourceApplySuccessEventArgs.Name = e.Name; + resourceApplySuccessEventArgs.ApplyPath = e.ApplyPath; + resourceApplySuccessEventArgs.ResourcePackPath = e.ResourcePackPath; + resourceApplySuccessEventArgs.Length = e.Length; + resourceApplySuccessEventArgs.CompressedLength = e.CompressedLength; + return resourceApplySuccessEventArgs; + } + + /// + /// 清理资源应用成功事件。 + /// + public override void Clear() + { + Name = null; + ApplyPath = null; + ResourcePackPath = null; + Length = 0; + CompressedLength = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplySuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplySuccessEventArgs.cs.meta new file mode 100644 index 0000000..a4286d0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceApplySuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5a9d46578a27a441a20e8578c940b42 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceComponent.cs new file mode 100644 index 0000000..ae3612d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceComponent.cs @@ -0,0 +1,1525 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Download; +using GameFramework.FileSystem; +using GameFramework.ObjectPool; +using GameFramework.Resource; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Resource")] + public sealed class ResourceComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + private const int OneMegaBytes = 1024 * 1024; + + private IResourceManager m_ResourceManager = null; + private EventComponent m_EventComponent = null; + private bool m_EditorResourceMode = false; + private bool m_ForceUnloadUnusedAssets = false; + private bool m_PreorderUnloadUnusedAssets = false; + private bool m_PerformGCCollect = false; + private AsyncOperation m_AsyncOperation = null; + private float m_LastUnloadUnusedAssetsOperationElapseSeconds = 0f; + private ResourceHelperBase m_ResourceHelper = null; + + [SerializeField] + private ResourceMode m_ResourceMode = ResourceMode.Package; + + [SerializeField] + private ReadWritePathType m_ReadWritePathType = ReadWritePathType.Unspecified; + + [SerializeField] + private float m_MinUnloadUnusedAssetsInterval = 60f; + + [SerializeField] + private float m_MaxUnloadUnusedAssetsInterval = 300f; + + [SerializeField] + private float m_AssetAutoReleaseInterval = 60f; + + [SerializeField] + private int m_AssetCapacity = 64; + + [SerializeField] + private float m_AssetExpireTime = 60f; + + [SerializeField] + private int m_AssetPriority = 0; + + [SerializeField] + private float m_ResourceAutoReleaseInterval = 60f; + + [SerializeField] + private int m_ResourceCapacity = 16; + + [SerializeField] + private float m_ResourceExpireTime = 60f; + + [SerializeField] + private int m_ResourcePriority = 0; + + [SerializeField] + private string m_UpdatePrefixUri = null; + + [SerializeField] + private int m_GenerateReadWriteVersionListLength = OneMegaBytes; + + [SerializeField] + private int m_UpdateRetryCount = 3; + + [SerializeField] + private Transform m_InstanceRoot = null; + + [SerializeField] + private string m_ResourceHelperTypeName = "UnityGameFramework.Runtime.DefaultResourceHelper"; + + [SerializeField] + private ResourceHelperBase m_CustomResourceHelper = null; + + [SerializeField] + private string m_LoadResourceAgentHelperTypeName = "UnityGameFramework.Runtime.DefaultLoadResourceAgentHelper"; + + [SerializeField] + private LoadResourceAgentHelperBase m_CustomLoadResourceAgentHelper = null; + + [SerializeField] + private int m_LoadResourceAgentHelperCount = 3; + + /// + /// 获取资源只读路径。 + /// + public string ReadOnlyPath + { + get + { + return m_ResourceManager.ReadOnlyPath; + } + } + + /// + /// 获取资源读写路径。 + /// + public string ReadWritePath + { + get + { + return m_ResourceManager.ReadWritePath; + } + } + + /// + /// 获取资源模式。 + /// + public ResourceMode ResourceMode + { + get + { + return m_ResourceManager.ResourceMode; + } + } + + /// + /// 获取资源读写路径类型。 + /// + public ReadWritePathType ReadWritePathType + { + get + { + return m_ReadWritePathType; + } + } + + /// + /// 设置当前变体。 + /// + public string CurrentVariant + { + get + { + return m_ResourceManager.CurrentVariant; + } + } + + /// + /// 获取单机模式版本资源列表序列化器。 + /// + public PackageVersionListSerializer PackageVersionListSerializer + { + get + { + return m_ResourceManager.PackageVersionListSerializer; + } + } + + /// + /// 获取可更新模式版本资源列表序列化器。 + /// + public UpdatableVersionListSerializer UpdatableVersionListSerializer + { + get + { + return m_ResourceManager.UpdatableVersionListSerializer; + } + } + + /// + /// 获取本地只读区版本资源列表序列化器。 + /// + public ReadOnlyVersionListSerializer ReadOnlyVersionListSerializer + { + get + { + return m_ResourceManager.ReadOnlyVersionListSerializer; + } + } + + /// + /// 获取本地读写区版本资源列表序列化器。 + /// + public ReadWriteVersionListSerializer ReadWriteVersionListSerializer + { + get + { + return m_ResourceManager.ReadWriteVersionListSerializer; + } + } + + /// + /// 获取资源包版本资源列表序列化器。 + /// + public ResourcePackVersionListSerializer ResourcePackVersionListSerializer + { + get + { + return m_ResourceManager.ResourcePackVersionListSerializer; + } + } + + /// + /// 获取无用资源释放的等待时长,以秒为单位。 + /// + public float LastUnloadUnusedAssetsOperationElapseSeconds + { + get + { + return m_LastUnloadUnusedAssetsOperationElapseSeconds; + } + } + + /// + /// 获取或设置无用资源释放的最小间隔时间,以秒为单位。 + /// + public float MinUnloadUnusedAssetsInterval + { + get + { + return m_MinUnloadUnusedAssetsInterval; + } + set + { + m_MinUnloadUnusedAssetsInterval = value; + } + } + + /// + /// 获取或设置无用资源释放的最大间隔时间,以秒为单位。 + /// + public float MaxUnloadUnusedAssetsInterval + { + get + { + return m_MaxUnloadUnusedAssetsInterval; + } + set + { + m_MaxUnloadUnusedAssetsInterval = value; + } + } + + /// + /// 获取当前资源适用的游戏版本号。 + /// + public string ApplicableGameVersion + { + get + { + return m_ResourceManager.ApplicableGameVersion; + } + } + + /// + /// 获取当前内部资源版本号。 + /// + public int InternalResourceVersion + { + get + { + return m_ResourceManager.InternalResourceVersion; + } + } + + /// + /// 获取资源数量。 + /// + public int AssetCount + { + get + { + return m_ResourceManager.AssetCount; + } + } + + /// + /// 获取资源数量。 + /// + public int ResourceCount + { + get + { + return m_ResourceManager.ResourceCount; + } + } + + /// + /// 获取资源组数量。 + /// + public int ResourceGroupCount + { + get + { + return m_ResourceManager.ResourceGroupCount; + } + } + + /// + /// 获取或设置资源更新下载地址。 + /// + public string UpdatePrefixUri + { + get + { + return m_ResourceManager.UpdatePrefixUri; + } + set + { + m_ResourceManager.UpdatePrefixUri = m_UpdatePrefixUri = value; + } + } + + public string HotUpdateScripts; + public string OtherHotUpdateScripts; + + /// + /// 获取或设置每更新多少字节的资源,重新生成一次版本资源列表。 + /// + public int GenerateReadWriteVersionListLength + { + get + { + return m_ResourceManager.GenerateReadWriteVersionListLength; + } + set + { + m_ResourceManager.GenerateReadWriteVersionListLength = m_GenerateReadWriteVersionListLength = value; + } + } + + /// + /// 获取正在应用的资源包路径。 + /// + public string ApplyingResourcePackPath + { + get + { + return m_ResourceManager.ApplyingResourcePackPath; + } + } + + /// + /// 获取等待应用资源数量。 + /// + public int ApplyWaitingCount + { + get + { + return m_ResourceManager.ApplyWaitingCount; + } + } + + /// + /// 获取或设置资源更新重试次数。 + /// + public int UpdateRetryCount + { + get + { + return m_ResourceManager.UpdateRetryCount; + } + set + { + m_ResourceManager.UpdateRetryCount = m_UpdateRetryCount = value; + } + } + + /// + /// 获取正在更新的资源组。 + /// + public IResourceGroup UpdatingResourceGroup + { + get + { + return m_ResourceManager.UpdatingResourceGroup; + } + } + + /// + /// 获取等待更新资源数量。 + /// + public int UpdateWaitingCount + { + get + { + return m_ResourceManager.UpdateWaitingCount; + } + } + + /// + /// 获取使用时下载的等待更新资源数量。 + /// + public int UpdateWaitingWhilePlayingCount + { + get + { + return m_ResourceManager.UpdateWaitingWhilePlayingCount; + } + } + + /// + /// 获取候选更新资源数量。 + /// + public int UpdateCandidateCount + { + get + { + return m_ResourceManager.UpdateCandidateCount; + } + } + + /// + /// 获取加载资源代理总数量。 + /// + public int LoadTotalAgentCount + { + get + { + return m_ResourceManager.LoadTotalAgentCount; + } + } + + /// + /// 获取可用加载资源代理数量。 + /// + public int LoadFreeAgentCount + { + get + { + return m_ResourceManager.LoadFreeAgentCount; + } + } + + /// + /// 获取工作中加载资源代理数量。 + /// + public int LoadWorkingAgentCount + { + get + { + return m_ResourceManager.LoadWorkingAgentCount; + } + } + + /// + /// 获取等待加载资源任务数量。 + /// + public int LoadWaitingTaskCount + { + get + { + return m_ResourceManager.LoadWaitingTaskCount; + } + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + public float AssetAutoReleaseInterval + { + get + { + return m_ResourceManager.AssetAutoReleaseInterval; + } + set + { + m_ResourceManager.AssetAutoReleaseInterval = m_AssetAutoReleaseInterval = value; + } + } + + /// + /// 获取或设置资源对象池的容量。 + /// + public int AssetCapacity + { + get + { + return m_ResourceManager.AssetCapacity; + } + set + { + m_ResourceManager.AssetCapacity = m_AssetCapacity = value; + } + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + public float AssetExpireTime + { + get + { + return m_ResourceManager.AssetExpireTime; + } + set + { + m_ResourceManager.AssetExpireTime = m_AssetExpireTime = value; + } + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + public int AssetPriority + { + get + { + return m_ResourceManager.AssetPriority; + } + set + { + m_ResourceManager.AssetPriority = m_AssetPriority = value; + } + } + + /// + /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 + /// + public float ResourceAutoReleaseInterval + { + get + { + return m_ResourceManager.ResourceAutoReleaseInterval; + } + set + { + m_ResourceManager.ResourceAutoReleaseInterval = m_ResourceAutoReleaseInterval = value; + } + } + + /// + /// 获取或设置资源对象池的容量。 + /// + public int ResourceCapacity + { + get + { + return m_ResourceManager.ResourceCapacity; + } + set + { + m_ResourceManager.ResourceCapacity = m_ResourceCapacity = value; + } + } + + /// + /// 获取或设置资源对象池对象过期秒数。 + /// + public float ResourceExpireTime + { + get + { + return m_ResourceManager.ResourceExpireTime; + } + set + { + m_ResourceManager.ResourceExpireTime = m_ResourceExpireTime = value; + } + } + + /// + /// 获取或设置资源对象池的优先级。 + /// + public int ResourcePriority + { + get + { + return m_ResourceManager.ResourcePriority; + } + set + { + m_ResourceManager.ResourcePriority = m_ResourcePriority = value; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + } + + private void Start() + { + BaseComponent baseComponent = GameEntry.GetComponent(); + if (baseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + m_EditorResourceMode = baseComponent.EditorResourceMode; + m_ResourceManager = m_EditorResourceMode ? baseComponent.EditorResourceHelper : GameFrameworkEntry.GetModule(); + if (m_ResourceManager == null) + { + Log.Fatal("Resource manager is invalid."); + return; + } + + m_ResourceManager.ResourceVerifyStart += OnResourceVerifyStart; + m_ResourceManager.ResourceVerifySuccess += OnResourceVerifySuccess; + m_ResourceManager.ResourceVerifyFailure += OnResourceVerifyFailure; + m_ResourceManager.ResourceApplyStart += OnResourceApplyStart; + m_ResourceManager.ResourceApplySuccess += OnResourceApplySuccess; + m_ResourceManager.ResourceApplyFailure += OnResourceApplyFailure; + m_ResourceManager.ResourceUpdateStart += OnResourceUpdateStart; + m_ResourceManager.ResourceUpdateChanged += OnResourceUpdateChanged; + m_ResourceManager.ResourceUpdateSuccess += OnResourceUpdateSuccess; + m_ResourceManager.ResourceUpdateFailure += OnResourceUpdateFailure; + m_ResourceManager.ResourceUpdateAllComplete += OnResourceUpdateAllComplete; + + if (Application.platform == RuntimePlatform.Android) + { + //Application.streamingAssetsPath安卓下路径为"jar:file://" + Application.dataPath + "!/assets" + //分包后是 + string appDataPath = Application.dataPath; + var tmp = System.IO.Path.GetDirectoryName(appDataPath); + tmp = tmp + "/split_base_assets.apk" + "!/assets"; + if (System.IO.File.Exists(tmp)) + { + appDataPath = "jar:file://" + tmp; + m_ResourceManager.SetReadOnlyPath(appDataPath); + } + else + { + m_ResourceManager.SetReadOnlyPath(Application.streamingAssetsPath); + } + } + else + { + m_ResourceManager.SetReadOnlyPath(Application.streamingAssetsPath); + } + + if (m_ReadWritePathType == ReadWritePathType.TemporaryCache) + { + m_ResourceManager.SetReadWritePath(Application.temporaryCachePath); + } + else + { + if (m_ReadWritePathType == ReadWritePathType.Unspecified) + { + m_ReadWritePathType = ReadWritePathType.PersistentData; + } + + m_ResourceManager.SetReadWritePath(Application.persistentDataPath); + } + + if (m_EditorResourceMode) + { + return; + } + + SetResourceMode(m_ResourceMode); + m_ResourceManager.SetObjectPoolManager(GameFrameworkEntry.GetModule()); + m_ResourceManager.SetFileSystemManager(GameFrameworkEntry.GetModule()); + m_ResourceManager.SetDownloadManager(GameFrameworkEntry.GetModule()); + m_ResourceManager.AssetAutoReleaseInterval = m_AssetAutoReleaseInterval; + m_ResourceManager.AssetCapacity = m_AssetCapacity; + m_ResourceManager.AssetExpireTime = m_AssetExpireTime; + m_ResourceManager.AssetPriority = m_AssetPriority; + m_ResourceManager.ResourceAutoReleaseInterval = m_ResourceAutoReleaseInterval; + m_ResourceManager.ResourceCapacity = m_ResourceCapacity; + m_ResourceManager.ResourceExpireTime = m_ResourceExpireTime; + m_ResourceManager.ResourcePriority = m_ResourcePriority; + if (m_ResourceMode == ResourceMode.Updatable || m_ResourceMode == ResourceMode.UpdatableWhilePlaying) + { + m_ResourceManager.UpdatePrefixUri = m_UpdatePrefixUri; + m_ResourceManager.GenerateReadWriteVersionListLength = m_GenerateReadWriteVersionListLength; + m_ResourceManager.UpdateRetryCount = m_UpdateRetryCount; + } + + m_ResourceHelper = Helper.CreateHelper(m_ResourceHelperTypeName, m_CustomResourceHelper); + if (m_ResourceHelper == null) + { + Log.Error("Can not create resource helper."); + return; + } + + m_ResourceHelper.name = "Resource Helper"; + Transform transform = m_ResourceHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_ResourceManager.SetResourceHelper(m_ResourceHelper); + + if (m_InstanceRoot == null) + { + m_InstanceRoot = new GameObject("Load Resource Agent Instances").transform; + m_InstanceRoot.SetParent(gameObject.transform); + m_InstanceRoot.localScale = Vector3.one; + } + + for (int i = 0; i < m_LoadResourceAgentHelperCount; i++) + { + AddLoadResourceAgentHelper(i); + } + } + + private void Update() + { + m_LastUnloadUnusedAssetsOperationElapseSeconds += Time.unscaledDeltaTime; + if (m_AsyncOperation == null && (m_ForceUnloadUnusedAssets || m_LastUnloadUnusedAssetsOperationElapseSeconds >= m_MaxUnloadUnusedAssetsInterval || m_PreorderUnloadUnusedAssets && m_LastUnloadUnusedAssetsOperationElapseSeconds >= m_MinUnloadUnusedAssetsInterval)) + { + Log.Info("Unload unused assets..."); + m_ForceUnloadUnusedAssets = false; + m_PreorderUnloadUnusedAssets = false; + m_LastUnloadUnusedAssetsOperationElapseSeconds = 0f; + m_AsyncOperation = Resources.UnloadUnusedAssets(); + } + + if (m_AsyncOperation != null && m_AsyncOperation.isDone) + { + m_AsyncOperation = null; + if (m_PerformGCCollect) + { + Log.Info("GC.Collect..."); + m_PerformGCCollect = false; + GC.Collect(); + } + } + } + + /// + /// 设置资源模式。 + /// + /// 资源模式。 + public void SetResourceMode(ResourceMode resourceMode) + { + m_ResourceManager.SetResourceMode(resourceMode); + switch (resourceMode) + { + case ResourceMode.Package: + m_ResourceManager.PackageVersionListSerializer.RegisterDeserializeCallback(0, BuiltinVersionListSerializer.PackageVersionListDeserializeCallback_V0); + m_ResourceManager.PackageVersionListSerializer.RegisterDeserializeCallback(1, BuiltinVersionListSerializer.PackageVersionListDeserializeCallback_V1); + m_ResourceManager.PackageVersionListSerializer.RegisterDeserializeCallback(2, BuiltinVersionListSerializer.PackageVersionListDeserializeCallback_V2); + break; + + case ResourceMode.Updatable: + case ResourceMode.UpdatableWhilePlaying: + m_ResourceManager.UpdatableVersionListSerializer.RegisterDeserializeCallback(0, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V0); + m_ResourceManager.UpdatableVersionListSerializer.RegisterDeserializeCallback(1, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V1); + m_ResourceManager.UpdatableVersionListSerializer.RegisterDeserializeCallback(2, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V2); + + m_ResourceManager.UpdatableVersionListSerializer.RegisterTryGetValueCallback(0, BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback_V0); + m_ResourceManager.UpdatableVersionListSerializer.RegisterTryGetValueCallback(1, BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback_V1_V2); + m_ResourceManager.UpdatableVersionListSerializer.RegisterTryGetValueCallback(2, BuiltinVersionListSerializer.UpdatableVersionListTryGetValueCallback_V1_V2); + + m_ResourceManager.ReadOnlyVersionListSerializer.RegisterDeserializeCallback(0, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V0); + m_ResourceManager.ReadOnlyVersionListSerializer.RegisterDeserializeCallback(1, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V1); + m_ResourceManager.ReadOnlyVersionListSerializer.RegisterDeserializeCallback(2, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V2); + + m_ResourceManager.ReadWriteVersionListSerializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V0); + m_ResourceManager.ReadWriteVersionListSerializer.RegisterSerializeCallback(1, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V1); + m_ResourceManager.ReadWriteVersionListSerializer.RegisterSerializeCallback(2, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V2); + + m_ResourceManager.ReadWriteVersionListSerializer.RegisterDeserializeCallback(0, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V0); + m_ResourceManager.ReadWriteVersionListSerializer.RegisterDeserializeCallback(1, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V1); + m_ResourceManager.ReadWriteVersionListSerializer.RegisterDeserializeCallback(2, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V2); + + m_ResourceManager.ResourcePackVersionListSerializer.RegisterDeserializeCallback(0, BuiltinVersionListSerializer.ResourcePackVersionListDeserializeCallback_V0); + break; + } + } + + /// + /// 设置当前变体。 + /// + /// 当前变体。 + public void SetCurrentVariant(string currentVariant) + { + m_ResourceManager.SetCurrentVariant(!string.IsNullOrEmpty(currentVariant) ? currentVariant : null); + } + + /// + /// 设置解密资源回调函数。 + /// + /// 要设置的解密资源回调函数。 + /// 如果不设置,将使用默认的解密资源回调函数。 + public void SetDecryptResourceCallback(DecryptResourceCallback decryptResourceCallback) + { + m_ResourceManager.SetDecryptResourceCallback(decryptResourceCallback); + } + + /// + /// 预订执行释放未被使用的资源。 + /// + /// 是否使用垃圾回收。 + public void UnloadUnusedAssets(bool performGCCollect) + { + m_PreorderUnloadUnusedAssets = true; + if (performGCCollect) + { + m_PerformGCCollect = performGCCollect; + } + } + + /// + /// 强制执行释放未被使用的资源。 + /// + /// 是否使用垃圾回收。 + public void ForceUnloadUnusedAssets(bool performGCCollect) + { + m_ForceUnloadUnusedAssets = true; + if (performGCCollect) + { + m_PerformGCCollect = performGCCollect; + } + } + + /// + /// 使用单机模式并初始化资源。 + /// + /// 使用单机模式并初始化资源完成时的回调函数。 + public void InitResources(InitResourcesCompleteCallback initResourcesCompleteCallback) + { + m_ResourceManager.InitResources(initResourcesCompleteCallback); + } + + /// + /// 使用可更新模式并检查版本资源列表。 + /// + /// 最新的内部资源版本号。 + /// 检查版本资源列表结果。 + public CheckVersionListResult CheckVersionList(int latestInternalResourceVersion) + { + return m_ResourceManager.CheckVersionList(latestInternalResourceVersion); + } + + /// + /// 使用可更新模式并更新版本资源列表。 + /// + /// 版本资源列表大小。 + /// 版本资源列表哈希值。 + /// 版本资源列表压缩后大小。 + /// 版本资源列表压缩后哈希值。 + /// 版本资源列表更新回调函数集。 + public void UpdateVersionList(int versionListLength, int versionListHashCode, int versionListCompressedLength, int versionListCompressedHashCode, UpdateVersionListCallbacks updateVersionListCallbacks) + { + m_ResourceManager.UpdateVersionList(versionListLength, versionListHashCode, versionListCompressedLength, versionListCompressedHashCode, updateVersionListCallbacks); + } + + /// + /// 使用可更新模式并校验资源。 + /// + /// 使用可更新模式并校验资源完成时的回调函数。 + public void VerifyResources(VerifyResourcesCompleteCallback verifyResourcesCompleteCallback) + { + m_ResourceManager.VerifyResources(0, verifyResourcesCompleteCallback); + } + + /// + /// 使用可更新模式并校验资源。 + /// + /// 每帧至少校验资源的大小,以字节为单位。 + /// 使用可更新模式并校验资源完成时的回调函数。 + public void VerifyResources(int verifyResourceLengthPerFrame, VerifyResourcesCompleteCallback verifyResourcesCompleteCallback) + { + m_ResourceManager.VerifyResources(verifyResourceLengthPerFrame, verifyResourcesCompleteCallback); + } + + /// + /// 使用可更新模式并检查资源。 + /// + /// 使用可更新模式并检查资源完成时的回调函数。 + public void CheckResources(CheckResourcesCompleteCallback checkResourcesCompleteCallback) + { + m_ResourceManager.CheckResources(false, checkResourcesCompleteCallback); + } + + /// + /// 使用可更新模式并检查资源。 + /// + /// 是否忽略处理其它变体的资源,若不忽略,将会移除其它变体的资源。 + /// 使用可更新模式并检查资源完成时的回调函数。 + public void CheckResources(bool ignoreOtherVariant, CheckResourcesCompleteCallback checkResourcesCompleteCallback) + { + m_ResourceManager.CheckResources(ignoreOtherVariant, checkResourcesCompleteCallback); + } + + /// + /// 使用可更新模式并应用资源包资源。 + /// + /// 要应用的资源包路径。 + /// 使用可更新模式并应用资源包资源完成时的回调函数。 + public void ApplyResources(string resourcePackPath, ApplyResourcesCompleteCallback applyResourcesCompleteCallback) + { + m_ResourceManager.ApplyResources(resourcePackPath, applyResourcesCompleteCallback); + } + + /// + /// 使用可更新模式并更新所有资源。 + /// + /// 使用可更新模式并更新默认资源组完成时的回调函数。 + public void UpdateResources(UpdateResourcesCompleteCallback updateResourcesCompleteCallback) + { + m_ResourceManager.UpdateResources(updateResourcesCompleteCallback); + } + + /// + /// 使用可更新模式并更新指定资源组的资源。 + /// + /// 要更新的资源组名称。 + /// 使用可更新模式并更新指定资源组完成时的回调函数。 + public void UpdateResources(string resourceGroupName, UpdateResourcesCompleteCallback updateResourcesCompleteCallback) + { + m_ResourceManager.UpdateResources(resourceGroupName, updateResourcesCompleteCallback); + } + + /// + /// 停止更新资源。 + /// + public void StopUpdateResources() + { + m_ResourceManager.StopUpdateResources(); + } + + /// + /// 校验资源包。 + /// + /// 要校验的资源包路径。 + /// 是否校验资源包成功。 + public bool VerifyResourcePack(string resourcePackPath) + { + return m_ResourceManager.VerifyResourcePack(resourcePackPath); + } + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + public TaskInfo[] GetAllLoadAssetInfos() + { + return m_ResourceManager.GetAllLoadAssetInfos(); + } + + /// + /// 获取所有加载资源任务的信息。 + /// + /// 所有加载资源任务的信息。 + public void GetAllLoadAssetInfos(List results) + { + m_ResourceManager.GetAllLoadAssetInfos(results); + } + + /// + /// 检查资源是否存在。 + /// + /// 要检查资源的名称。 + /// 检查资源是否存在的结果。 + public HasAssetResult HasAsset(string assetName) + { + return m_ResourceManager.HasAsset(assetName); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks) + { + LoadAsset(assetName, null, DefaultPriority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, Type assetType, LoadAssetCallbacks loadAssetCallbacks) + { + LoadAsset(assetName, assetType, DefaultPriority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, int priority, LoadAssetCallbacks loadAssetCallbacks) + { + LoadAsset(assetName, null, priority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + LoadAsset(assetName, null, DefaultPriority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + public void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks) + { + LoadAsset(assetName, assetType, priority, loadAssetCallbacks, null); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, Type assetType, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + LoadAsset(assetName, assetType, DefaultPriority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + LoadAsset(assetName, null, priority, loadAssetCallbacks, userData); + } + + /// + /// 异步加载资源。 + /// + /// 要加载资源的名称。 + /// 要加载资源的类型。 + /// 加载资源的优先级。 + /// 加载资源回调函数集。 + /// 用户自定义数据。 + public void LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData) + { + if (string.IsNullOrEmpty(assetName)) + { + Log.Error("Asset name is invalid."); + return; + } + + if (!assetName.StartsWith("Assets/", StringComparison.Ordinal)) + { + Log.Error("Asset name '{0}' is invalid.", assetName); + return; + } + + m_ResourceManager.LoadAsset(assetName, assetType, priority, loadAssetCallbacks, userData); + } + + /// + /// 卸载资源。 + /// + /// 要卸载的资源。 + public void UnloadAsset(object asset) + { + m_ResourceManager.UnloadAsset(asset); + } + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源的实际路径。 + /// 此方法仅适用于二进制资源存储在磁盘(而非文件系统)中的情况。若二进制资源存储在文件系统中时,返回值将始终为空。 + public string GetBinaryPath(string binaryAssetName) + { + return m_ResourceManager.GetBinaryPath(binaryAssetName); + } + + /// + /// 获取二进制资源的实际路径。 + /// + /// 要获取实际路径的二进制资源的名称。 + /// 二进制资源是否存储在只读区中。 + /// 二进制资源是否存储在文件系统中。 + /// 二进制资源或存储二进制资源的文件系统,相对于只读区或者读写区的相对路径。 + /// 若二进制资源存储在文件系统中,则指示二进制资源在文件系统中的名称,否则此参数返回空。 + /// 是否获取二进制资源的实际路径成功。 + public bool GetBinaryPath(string binaryAssetName, out bool storageInReadOnly, out bool storageInFileSystem, out string relativePath, out string fileName) + { + return m_ResourceManager.GetBinaryPath(binaryAssetName, out storageInReadOnly, out storageInFileSystem, out relativePath, out fileName); + } + + /// + /// 获取二进制资源的长度。 + /// + /// 要获取长度的二进制资源的名称。 + /// 二进制资源的长度。 + public int GetBinaryLength(string binaryAssetName) + { + return m_ResourceManager.GetBinaryLength(binaryAssetName); + } + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + public void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks) + { + LoadBinary(binaryAssetName, loadBinaryCallbacks, null); + } + + /// + /// 异步加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 加载二进制资源回调函数集。 + /// 用户自定义数据。 + public void LoadBinary(string binaryAssetName, LoadBinaryCallbacks loadBinaryCallbacks, object userData) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + Log.Error("Binary asset name is invalid."); + return; + } + + if (!binaryAssetName.StartsWith("Assets/", StringComparison.Ordinal)) + { + Log.Error("Binary asset name '{0}' is invalid.", binaryAssetName); + return; + } + + m_ResourceManager.LoadBinary(binaryAssetName, loadBinaryCallbacks, userData); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + public byte[] LoadBinaryFromFileSystem(string binaryAssetName) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + Log.Error("Binary asset name is invalid."); + return null; + } + + if (!binaryAssetName.StartsWith("Assets/", StringComparison.Ordinal)) + { + Log.Error("Binary asset name '{0}' is invalid.", binaryAssetName); + return null; + } + + return m_ResourceManager.LoadBinaryFromFileSystem(binaryAssetName); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer) + { + if (buffer == null) + { + Log.Error("Buffer is invalid."); + return 0; + } + + return LoadBinaryFromFileSystem(binaryAssetName, buffer, 0, buffer.Length); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex) + { + if (buffer == null) + { + Log.Error("Buffer is invalid."); + return 0; + } + + return LoadBinaryFromFileSystem(binaryAssetName, buffer, startIndex, buffer.Length - startIndex); + } + + /// + /// 从文件系统中加载二进制资源。 + /// + /// 要加载二进制资源的名称。 + /// 存储加载二进制资源的二进制流。 + /// 存储加载二进制资源的二进制流的起始位置。 + /// 存储加载二进制资源的二进制流的长度。 + /// 实际加载了多少字节。 + public int LoadBinaryFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + Log.Error("Binary asset name is invalid."); + return 0; + } + + if (!binaryAssetName.StartsWith("Assets/", StringComparison.Ordinal)) + { + Log.Error("Binary asset name '{0}' is invalid.", binaryAssetName); + return 0; + } + + if (buffer == null) + { + Log.Error("Buffer is invalid."); + return 0; + } + + return m_ResourceManager.LoadBinaryFromFileSystem(binaryAssetName, buffer, startIndex, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + public byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int length) + { + return LoadBinarySegmentFromFileSystem(binaryAssetName, 0, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 要加载片段的长度。 + /// 存储加载二进制资源片段内容的二进制流。 + public byte[] LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + Log.Error("Binary asset name is invalid."); + return null; + } + + if (!binaryAssetName.StartsWith("Assets/", StringComparison.Ordinal)) + { + Log.Error("Binary asset name '{0}' is invalid.", binaryAssetName); + return null; + } + + return m_ResourceManager.LoadBinarySegmentFromFileSystem(binaryAssetName, offset, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer) + { + if (buffer == null) + { + Log.Error("Buffer is invalid."); + return 0; + } + + return LoadBinarySegmentFromFileSystem(binaryAssetName, 0, buffer, 0, buffer.Length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer, int length) + { + return LoadBinarySegmentFromFileSystem(binaryAssetName, 0, buffer, 0, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, byte[] buffer, int startIndex, int length) + { + return LoadBinarySegmentFromFileSystem(binaryAssetName, 0, buffer, startIndex, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer) + { + if (buffer == null) + { + Log.Error("Buffer is invalid."); + return 0; + } + + return LoadBinarySegmentFromFileSystem(binaryAssetName, offset, buffer, 0, buffer.Length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int length) + { + return LoadBinarySegmentFromFileSystem(binaryAssetName, offset, buffer, 0, length); + } + + /// + /// 从文件系统中加载二进制资源的片段。 + /// + /// 要加载片段的二进制资源的名称。 + /// 要加载片段的偏移。 + /// 存储加载二进制资源片段内容的二进制流。 + /// 存储加载二进制资源片段内容的二进制流的起始位置。 + /// 要加载片段的长度。 + /// 实际加载了多少字节。 + public int LoadBinarySegmentFromFileSystem(string binaryAssetName, int offset, byte[] buffer, int startIndex, int length) + { + if (string.IsNullOrEmpty(binaryAssetName)) + { + Log.Error("Binary asset name is invalid."); + return 0; + } + + if (!binaryAssetName.StartsWith("Assets/", StringComparison.Ordinal)) + { + Log.Error("Binary asset name '{0}' is invalid.", binaryAssetName); + return 0; + } + + if (buffer == null) + { + Log.Error("Buffer is invalid."); + return 0; + } + + return m_ResourceManager.LoadBinarySegmentFromFileSystem(binaryAssetName, offset, buffer, startIndex, length); + } + + /// + /// 检查资源组是否存在。 + /// + /// 要检查资源组的名称。 + /// 资源组是否存在。 + public bool HasResourceGroup(string resourceGroupName) + { + return m_ResourceManager.HasResourceGroup(resourceGroupName); + } + + /// + /// 获取默认资源组。 + /// + /// 默认资源组。 + public IResourceGroup GetResourceGroup() + { + return m_ResourceManager.GetResourceGroup(); + } + + /// + /// 获取资源组。 + /// + /// 要获取的资源组名称。 + /// 要获取的资源组。 + public IResourceGroup GetResourceGroup(string resourceGroupName) + { + return m_ResourceManager.GetResourceGroup(resourceGroupName); + } + + /// + /// 获取所有资源组。 + /// + /// 所有资源组。 + public IResourceGroup[] GetAllResourceGroups() + { + return m_ResourceManager.GetAllResourceGroups(); + } + + /// + /// 获取所有资源组。 + /// + /// 所有资源组。 + public void GetAllResourceGroups(List results) + { + m_ResourceManager.GetAllResourceGroups(results); + } + + /// + /// 获取资源组集合。 + /// + /// 要获取的资源组名称的集合。 + /// 要获取的资源组集合。 + public IResourceGroupCollection GetResourceGroupCollection(params string[] resourceGroupNames) + { + return m_ResourceManager.GetResourceGroupCollection(resourceGroupNames); + } + + /// + /// 获取资源组集合。 + /// + /// 要获取的资源组名称的集合。 + /// 要获取的资源组集合。 + public IResourceGroupCollection GetResourceGroupCollection(List resourceGroupNames) + { + return m_ResourceManager.GetResourceGroupCollection(resourceGroupNames); + } + + /// + /// 增加加载资源代理辅助器。 + /// + /// 加载资源代理辅助器索引。 + private void AddLoadResourceAgentHelper(int index) + { + LoadResourceAgentHelperBase loadResourceAgentHelper = Helper.CreateHelper(m_LoadResourceAgentHelperTypeName, m_CustomLoadResourceAgentHelper, index); + if (loadResourceAgentHelper == null) + { + Log.Error("Can not create load resource agent helper."); + return; + } + + loadResourceAgentHelper.name = Utility.Text.Format("Load Resource Agent Helper - {0}", index); + Transform transform = loadResourceAgentHelper.transform; + transform.SetParent(m_InstanceRoot); + transform.localScale = Vector3.one; + + m_ResourceManager.AddLoadResourceAgentHelper(loadResourceAgentHelper); + } + + private void OnResourceVerifyStart(object sender, GameFramework.Resource.ResourceVerifyStartEventArgs e) + { + m_EventComponent.Fire(this, ResourceVerifyStartEventArgs.Create(e)); + } + + private void OnResourceVerifySuccess(object sender, GameFramework.Resource.ResourceVerifySuccessEventArgs e) + { + m_EventComponent.Fire(this, ResourceVerifySuccessEventArgs.Create(e)); + } + + private void OnResourceVerifyFailure(object sender, GameFramework.Resource.ResourceVerifyFailureEventArgs e) + { + m_EventComponent.Fire(this, ResourceVerifyFailureEventArgs.Create(e)); + } + + private void OnResourceApplyStart(object sender, GameFramework.Resource.ResourceApplyStartEventArgs e) + { + m_EventComponent.Fire(this, ResourceApplyStartEventArgs.Create(e)); + } + + private void OnResourceApplySuccess(object sender, GameFramework.Resource.ResourceApplySuccessEventArgs e) + { + m_EventComponent.Fire(this, ResourceApplySuccessEventArgs.Create(e)); + } + + private void OnResourceApplyFailure(object sender, GameFramework.Resource.ResourceApplyFailureEventArgs e) + { + m_EventComponent.Fire(this, ResourceApplyFailureEventArgs.Create(e)); + } + + private void OnResourceUpdateStart(object sender, GameFramework.Resource.ResourceUpdateStartEventArgs e) + { + m_EventComponent.Fire(this, ResourceUpdateStartEventArgs.Create(e)); + } + + private void OnResourceUpdateChanged(object sender, GameFramework.Resource.ResourceUpdateChangedEventArgs e) + { + m_EventComponent.Fire(this, ResourceUpdateChangedEventArgs.Create(e)); + } + + private void OnResourceUpdateSuccess(object sender, GameFramework.Resource.ResourceUpdateSuccessEventArgs e) + { + m_EventComponent.Fire(this, ResourceUpdateSuccessEventArgs.Create(e)); + } + + private void OnResourceUpdateFailure(object sender, GameFramework.Resource.ResourceUpdateFailureEventArgs e) + { + m_EventComponent.Fire(this, ResourceUpdateFailureEventArgs.Create(e)); + } + + private void OnResourceUpdateAllComplete(object sender, GameFramework.Resource.ResourceUpdateAllCompleteEventArgs e) + { + m_EventComponent.Fire(this, ResourceUpdateAllCompleteEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceComponent.cs.meta new file mode 100644 index 0000000..8b99b82 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7eff66e40586ec14d8a301d416f17f1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceHelperBase.cs new file mode 100644 index 0000000..df016bf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceHelperBase.cs @@ -0,0 +1,40 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Resource; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源辅助器基类。 + /// + public abstract class ResourceHelperBase : MonoBehaviour, IResourceHelper + { + /// + /// 直接从指定文件路径加载数据流。 + /// + /// 文件路径。 + /// 加载数据流回调函数集。 + /// 用户自定义数据。 + public abstract void LoadBytes(string fileUri, LoadBytesCallbacks loadBytesCallbacks, object userData); + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + /// 卸载场景回调函数集。 + /// 用户自定义数据。 + public abstract void UnloadScene(string sceneAssetName, UnloadSceneCallbacks unloadSceneCallbacks, object userData); + + /// + /// 释放资源。 + /// + /// 要释放的资源。 + public abstract void Release(object objectToRelease); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceHelperBase.cs.meta new file mode 100644 index 0000000..d5bb43b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 231b6034e6f70794886826c9ba18dc2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs new file mode 100644 index 0000000..219c0a2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs @@ -0,0 +1,58 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源更新全部完成事件。 + /// + public sealed class ResourceUpdateAllCompleteEventArgs : GameEventArgs + { + /// + /// 资源更新全部完成事件编号。 + /// + public static readonly int EventId = typeof(ResourceUpdateAllCompleteEventArgs).GetHashCode(); + + /// + /// 初始化资源更新全部完成事件的新实例。 + /// + public ResourceUpdateAllCompleteEventArgs() + { + } + + /// + /// 获取资源更新全部完成事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 创建资源更新全部完成事件。 + /// + /// 内部事件。 + /// 创建的资源更新全部完成事件。 + public static ResourceUpdateAllCompleteEventArgs Create(GameFramework.Resource.ResourceUpdateAllCompleteEventArgs e) + { + return ReferencePool.Acquire(); + } + + /// + /// 清理资源更新全部完成事件。 + /// + public override void Clear() + { + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs.meta new file mode 100644 index 0000000..76f67ac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateAllCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2170354b236b90446bdd75a841140b52 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateChangedEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateChangedEventArgs.cs new file mode 100644 index 0000000..f117e3b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateChangedEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源更新改变事件。 + /// + public sealed class ResourceUpdateChangedEventArgs : GameEventArgs + { + /// + /// 资源更新改变事件编号。 + /// + public static readonly int EventId = typeof(ResourceUpdateChangedEventArgs).GetHashCode(); + + /// + /// 初始化资源更新改变事件的新实例。 + /// + public ResourceUpdateChangedEventArgs() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0; + CompressedLength = 0; + } + + /// + /// 获取资源更新改变事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前下载大小。 + /// + public int CurrentLength + { + get; + private set; + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get; + private set; + } + + /// + /// 创建资源更新改变事件。 + /// + /// 内部事件。 + /// 创建的资源更新改变事件。 + public static ResourceUpdateChangedEventArgs Create(GameFramework.Resource.ResourceUpdateChangedEventArgs e) + { + ResourceUpdateChangedEventArgs resourceUpdateChangedEventArgs = ReferencePool.Acquire(); + resourceUpdateChangedEventArgs.Name = e.Name; + resourceUpdateChangedEventArgs.DownloadPath = e.DownloadPath; + resourceUpdateChangedEventArgs.DownloadUri = e.DownloadUri; + resourceUpdateChangedEventArgs.CurrentLength = e.CurrentLength; + resourceUpdateChangedEventArgs.CompressedLength = e.CompressedLength; + return resourceUpdateChangedEventArgs; + } + + /// + /// 清理资源更新改变事件。 + /// + public override void Clear() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0; + CompressedLength = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateChangedEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateChangedEventArgs.cs.meta new file mode 100644 index 0000000..c4fffdb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateChangedEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 578263f614242464495370d64b664c7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateFailureEventArgs.cs new file mode 100644 index 0000000..27f5757 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateFailureEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源更新失败事件。 + /// + public sealed class ResourceUpdateFailureEventArgs : GameEventArgs + { + /// + /// 资源更新失败事件编号。 + /// + public static readonly int EventId = typeof(ResourceUpdateFailureEventArgs).GetHashCode(); + + /// + /// 初始化资源更新失败事件的新实例。 + /// + public ResourceUpdateFailureEventArgs() + { + Name = null; + DownloadUri = null; + RetryCount = 0; + TotalRetryCount = 0; + ErrorMessage = null; + } + + /// + /// 获取资源更新失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取已重试次数。 + /// + public int RetryCount + { + get; + private set; + } + + /// + /// 获取设定的重试次数。 + /// + public int TotalRetryCount + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 创建资源更新失败事件。 + /// + /// 内部事件。 + /// 创建的资源更新失败事件。 + public static ResourceUpdateFailureEventArgs Create(GameFramework.Resource.ResourceUpdateFailureEventArgs e) + { + ResourceUpdateFailureEventArgs resourceUpdateFailureEventArgs = ReferencePool.Acquire(); + resourceUpdateFailureEventArgs.Name = e.Name; + resourceUpdateFailureEventArgs.DownloadUri = e.DownloadUri; + resourceUpdateFailureEventArgs.RetryCount = e.RetryCount; + resourceUpdateFailureEventArgs.TotalRetryCount = e.TotalRetryCount; + resourceUpdateFailureEventArgs.ErrorMessage = e.ErrorMessage; + return resourceUpdateFailureEventArgs; + } + + /// + /// 清理资源更新失败事件。 + /// + public override void Clear() + { + Name = null; + DownloadUri = null; + RetryCount = 0; + TotalRetryCount = 0; + ErrorMessage = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateFailureEventArgs.cs.meta new file mode 100644 index 0000000..36fddcf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6425ae0a812a24b4a863461585a7c7ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateStartEventArgs.cs new file mode 100644 index 0000000..14f191d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateStartEventArgs.cs @@ -0,0 +1,131 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源更新开始事件。 + /// + public sealed class ResourceUpdateStartEventArgs : GameEventArgs + { + /// + /// 资源更新开始事件编号。 + /// + public static readonly int EventId = typeof(ResourceUpdateStartEventArgs).GetHashCode(); + + /// + /// 初始化资源更新开始事件的新实例。 + /// + public ResourceUpdateStartEventArgs() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0; + CompressedLength = 0; + RetryCount = 0; + } + + /// + /// 获取资源更新开始事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取当前下载大小。 + /// + public int CurrentLength + { + get; + private set; + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get; + private set; + } + + /// + /// 获取已重试下载次数。 + /// + public int RetryCount + { + get; + private set; + } + + /// + /// 创建资源更新开始事件。 + /// + /// 内部事件。 + /// 创建的资源更新开始事件。 + public static ResourceUpdateStartEventArgs Create(GameFramework.Resource.ResourceUpdateStartEventArgs e) + { + ResourceUpdateStartEventArgs resourceUpdateStartEventArgs = ReferencePool.Acquire(); + resourceUpdateStartEventArgs.Name = e.Name; + resourceUpdateStartEventArgs.DownloadPath = e.DownloadPath; + resourceUpdateStartEventArgs.DownloadUri = e.DownloadUri; + resourceUpdateStartEventArgs.CurrentLength = e.CurrentLength; + resourceUpdateStartEventArgs.CompressedLength = e.CompressedLength; + resourceUpdateStartEventArgs.RetryCount = e.RetryCount; + return resourceUpdateStartEventArgs; + } + + /// + /// 清理资源更新开始事件。 + /// + public override void Clear() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + CurrentLength = 0; + CompressedLength = 0; + RetryCount = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateStartEventArgs.cs.meta new file mode 100644 index 0000000..2461868 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b52ac443f249b2549827406d63bcbc57 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateSuccessEventArgs.cs new file mode 100644 index 0000000..8438b3d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateSuccessEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源更新成功事件。 + /// + public sealed class ResourceUpdateSuccessEventArgs : GameEventArgs + { + /// + /// 资源更新成功事件编号。 + /// + public static readonly int EventId = typeof(ResourceUpdateSuccessEventArgs).GetHashCode(); + + /// + /// 初始化资源更新成功事件的新实例。 + /// + public ResourceUpdateSuccessEventArgs() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + Length = 0; + CompressedLength = 0; + } + + /// + /// 获取资源更新成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源下载后存放路径。 + /// + public string DownloadPath + { + get; + private set; + } + + /// + /// 获取下载地址。 + /// + public string DownloadUri + { + get; + private set; + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get; + private set; + } + + /// + /// 获取压缩后大小。 + /// + public int CompressedLength + { + get; + private set; + } + + /// + /// 创建资源更新成功事件。 + /// + /// 内部事件。 + /// 创建的资源更新成功事件。 + public static ResourceUpdateSuccessEventArgs Create(GameFramework.Resource.ResourceUpdateSuccessEventArgs e) + { + ResourceUpdateSuccessEventArgs resourceUpdateSuccessEventArgs = ReferencePool.Acquire(); + resourceUpdateSuccessEventArgs.Name = e.Name; + resourceUpdateSuccessEventArgs.DownloadPath = e.DownloadPath; + resourceUpdateSuccessEventArgs.DownloadUri = e.DownloadUri; + resourceUpdateSuccessEventArgs.Length = e.Length; + resourceUpdateSuccessEventArgs.CompressedLength = e.CompressedLength; + return resourceUpdateSuccessEventArgs; + } + + /// + /// 清理资源更新成功事件。 + /// + public override void Clear() + { + Name = null; + DownloadPath = null; + DownloadUri = null; + Length = 0; + CompressedLength = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateSuccessEventArgs.cs.meta new file mode 100644 index 0000000..2d27644 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceUpdateSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d652343468bb5eb489ea17764743a770 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyFailureEventArgs.cs new file mode 100644 index 0000000..326a22b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyFailureEventArgs.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源校验失败事件。 + /// + public sealed class ResourceVerifyFailureEventArgs : GameEventArgs + { + /// + /// 资源校验失败事件编号。 + /// + public static readonly int EventId = typeof(ResourceVerifyFailureEventArgs).GetHashCode(); + + /// + /// 初始化资源校验失败事件的新实例。 + /// + public ResourceVerifyFailureEventArgs() + { + Name = null; + } + + /// + /// 获取资源校验失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 创建资源校验失败事件。 + /// + /// 内部事件。 + /// 创建的资源校验失败事件。 + public static ResourceVerifyFailureEventArgs Create(GameFramework.Resource.ResourceVerifyFailureEventArgs e) + { + ResourceVerifyFailureEventArgs resourceVerifyFailureEventArgs = ReferencePool.Acquire(); + resourceVerifyFailureEventArgs.Name = e.Name; + return resourceVerifyFailureEventArgs; + } + + /// + /// 清理资源校验失败事件。 + /// + public override void Clear() + { + Name = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyFailureEventArgs.cs.meta new file mode 100644 index 0000000..98a87dc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7adfa3d08717d2d4f9ffb7052753a3bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyStartEventArgs.cs new file mode 100644 index 0000000..9879f0a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyStartEventArgs.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源校验开始事件。 + /// + public sealed class ResourceVerifyStartEventArgs : GameEventArgs + { + /// + /// 资源校验开始事件编号。 + /// + public static readonly int EventId = typeof(ResourceVerifyStartEventArgs).GetHashCode(); + + /// + /// 初始化资源校验开始事件的新实例。 + /// + public ResourceVerifyStartEventArgs() + { + Count = 0; + TotalLength = 0L; + } + + /// + /// 获取资源校验开始事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取要校验资源的数量。 + /// + public int Count + { + get; + private set; + } + + /// + /// 获取要校验资源的总大小。 + /// + public long TotalLength + { + get; + private set; + } + + /// + /// 创建资源校验开始事件。 + /// + /// 内部事件。 + /// 创建的资源校验开始事件。 + public static ResourceVerifyStartEventArgs Create(GameFramework.Resource.ResourceVerifyStartEventArgs e) + { + ResourceVerifyStartEventArgs resourceVerifyStartEventArgs = ReferencePool.Acquire(); + resourceVerifyStartEventArgs.Count = e.Count; + resourceVerifyStartEventArgs.TotalLength = e.TotalLength; + return resourceVerifyStartEventArgs; + } + + /// + /// 清理资源校验开始事件。 + /// + public override void Clear() + { + Count = 0; + TotalLength = 0L; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyStartEventArgs.cs.meta new file mode 100644 index 0000000..1def453 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifyStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 42cc09d13fb26744ab9fc5da7714f443 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifySuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifySuccessEventArgs.cs new file mode 100644 index 0000000..e90ac8a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifySuccessEventArgs.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 资源校验成功事件。 + /// + public sealed class ResourceVerifySuccessEventArgs : GameEventArgs + { + /// + /// 资源校验成功事件编号。 + /// + public static readonly int EventId = typeof(ResourceVerifySuccessEventArgs).GetHashCode(); + + /// + /// 初始化资源校验成功事件的新实例。 + /// + public ResourceVerifySuccessEventArgs() + { + Name = null; + Length = 0; + } + + /// + /// 获取资源校验成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取资源名称。 + /// + public string Name + { + get; + private set; + } + + /// + /// 获取资源大小。 + /// + public int Length + { + get; + private set; + } + + /// + /// 创建资源校验成功事件。 + /// + /// 内部事件。 + /// 创建的资源校验成功事件。 + public static ResourceVerifySuccessEventArgs Create(GameFramework.Resource.ResourceVerifySuccessEventArgs e) + { + ResourceVerifySuccessEventArgs resourceVerifySuccessEventArgs = ReferencePool.Acquire(); + resourceVerifySuccessEventArgs.Name = e.Name; + resourceVerifySuccessEventArgs.Length = e.Length; + return resourceVerifySuccessEventArgs; + } + + /// + /// 清理资源校验成功事件。 + /// + public override void Clear() + { + Name = null; + Length = 0; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifySuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifySuccessEventArgs.cs.meta new file mode 100644 index 0000000..d27f4c5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/ResourceVerifySuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4318e2ddfebdf804eaac67df48fd4a83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/SceneAsset.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/SceneAsset.cs new file mode 100644 index 0000000..c926b6f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/SceneAsset.cs @@ -0,0 +1,13 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + internal sealed class SceneAsset + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/SceneAsset.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/SceneAsset.cs.meta new file mode 100644 index 0000000..4f03827 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Resource/SceneAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed139c50a07e4544eb7ff7e75654d488 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene.meta new file mode 100644 index 0000000..1149c08 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 141ad46133ef8f54e9f4f0ac35f0da19 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/ActiveSceneChangedEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/ActiveSceneChangedEventArgs.cs new file mode 100644 index 0000000..21baa72 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/ActiveSceneChangedEventArgs.cs @@ -0,0 +1,85 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using UnityEngine.SceneManagement; + +namespace UnityGameFramework.Runtime +{ + /// + /// 激活场景被改变事件。 + /// + public sealed class ActiveSceneChangedEventArgs : GameEventArgs + { + /// + /// 激活场景被改变事件编号。 + /// + public static readonly int EventId = typeof(ActiveSceneChangedEventArgs).GetHashCode(); + + /// + /// 初始化激活场景被改变事件的新实例。 + /// + public ActiveSceneChangedEventArgs() + { + LastActiveScene = default(Scene); + ActiveScene = default(Scene); + } + + /// + /// 获取激活场景被改变事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取上一个被激活的场景。 + /// + public Scene LastActiveScene + { + get; + private set; + } + + /// + /// 获取被激活的场景。 + /// + public Scene ActiveScene + { + get; + private set; + } + + /// + /// 创建激活场景被改变事件。 + /// + /// 上一个被激活的场景。 + /// 被激活的场景。 + /// 创建的激活场景被改变事件。 + public static ActiveSceneChangedEventArgs Create(Scene lastActiveScene, Scene activeScene) + { + ActiveSceneChangedEventArgs activeSceneChangedEventArgs = ReferencePool.Acquire(); + activeSceneChangedEventArgs.LastActiveScene = lastActiveScene; + activeSceneChangedEventArgs.ActiveScene = activeScene; + return activeSceneChangedEventArgs; + } + + /// + /// 清理激活场景被改变事件。 + /// + public override void Clear() + { + LastActiveScene = default(Scene); + ActiveScene = default(Scene); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/ActiveSceneChangedEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/ActiveSceneChangedEventArgs.cs.meta new file mode 100644 index 0000000..4292983 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/ActiveSceneChangedEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41e284ba4b2e7b044b63702496b5b31f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs new file mode 100644 index 0000000..5040201 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs @@ -0,0 +1,119 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载场景时加载依赖资源事件。 + /// + public sealed class LoadSceneDependencyAssetEventArgs : GameEventArgs + { + /// + /// 加载场景时加载依赖资源事件编号。 + /// + public static readonly int EventId = typeof(LoadSceneDependencyAssetEventArgs).GetHashCode(); + + /// + /// 初始化加载场景时加载依赖资源事件的新实例。 + /// + public LoadSceneDependencyAssetEventArgs() + { + SceneAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取加载场景时加载依赖资源事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载场景时加载依赖资源事件。 + /// + /// 内部事件。 + /// 创建的加载场景时加载依赖资源事件。 + public static LoadSceneDependencyAssetEventArgs Create(GameFramework.Scene.LoadSceneDependencyAssetEventArgs e) + { + LoadSceneDependencyAssetEventArgs loadSceneDependencyAssetEventArgs = ReferencePool.Acquire(); + loadSceneDependencyAssetEventArgs.SceneAssetName = e.SceneAssetName; + loadSceneDependencyAssetEventArgs.DependencyAssetName = e.DependencyAssetName; + loadSceneDependencyAssetEventArgs.LoadedCount = e.LoadedCount; + loadSceneDependencyAssetEventArgs.TotalCount = e.TotalCount; + loadSceneDependencyAssetEventArgs.UserData = e.UserData; + return loadSceneDependencyAssetEventArgs; + } + + /// + /// 清理加载场景时加载依赖资源事件。 + /// + public override void Clear() + { + SceneAssetName = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..f80db9f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d79041cd45038b48acd126c6b44038a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneFailureEventArgs.cs new file mode 100644 index 0000000..603fa43 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneFailureEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载场景失败事件。 + /// + public sealed class LoadSceneFailureEventArgs : GameEventArgs + { + /// + /// 加载场景失败事件编号。 + /// + public static readonly int EventId = typeof(LoadSceneFailureEventArgs).GetHashCode(); + + /// + /// 初始化加载场景失败事件的新实例。 + /// + public LoadSceneFailureEventArgs() + { + SceneAssetName = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取加载场景失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载场景失败事件。 + /// + /// 内部事件。 + /// 创建的加载场景失败事件。 + public static LoadSceneFailureEventArgs Create(GameFramework.Scene.LoadSceneFailureEventArgs e) + { + LoadSceneFailureEventArgs loadSceneFailureEventArgs = ReferencePool.Acquire(); + loadSceneFailureEventArgs.SceneAssetName = e.SceneAssetName; + loadSceneFailureEventArgs.ErrorMessage = e.ErrorMessage; + loadSceneFailureEventArgs.UserData = e.UserData; + return loadSceneFailureEventArgs; + } + + /// + /// 清理加载场景失败事件。 + /// + public override void Clear() + { + SceneAssetName = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneFailureEventArgs.cs.meta new file mode 100644 index 0000000..559b54d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b164a3668d54e5418bb662588aa3805 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneSuccessEventArgs.cs new file mode 100644 index 0000000..83ce250 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneSuccessEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载场景成功事件。 + /// + public sealed class LoadSceneSuccessEventArgs : GameEventArgs + { + /// + /// 加载场景成功事件编号。 + /// + public static readonly int EventId = typeof(LoadSceneSuccessEventArgs).GetHashCode(); + + /// + /// 初始化加载场景成功事件的新实例。 + /// + public LoadSceneSuccessEventArgs() + { + SceneAssetName = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取加载场景成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载场景成功事件。 + /// + /// 内部事件。 + /// 创建的加载场景成功事件。 + public static LoadSceneSuccessEventArgs Create(GameFramework.Scene.LoadSceneSuccessEventArgs e) + { + LoadSceneSuccessEventArgs loadSceneSuccessEventArgs = ReferencePool.Acquire(); + loadSceneSuccessEventArgs.SceneAssetName = e.SceneAssetName; + loadSceneSuccessEventArgs.Duration = e.Duration; + loadSceneSuccessEventArgs.UserData = e.UserData; + return loadSceneSuccessEventArgs; + } + + /// + /// 清理加载场景成功事件。 + /// + public override void Clear() + { + SceneAssetName = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneSuccessEventArgs.cs.meta new file mode 100644 index 0000000..dd0a63c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05add94fc5037024c87844fd64e1ab71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneUpdateEventArgs.cs new file mode 100644 index 0000000..3eccd9a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneUpdateEventArgs.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 加载场景更新事件。 + /// + public sealed class LoadSceneUpdateEventArgs : GameEventArgs + { + /// + /// 加载场景更新事件编号。 + /// + public static readonly int EventId = typeof(LoadSceneUpdateEventArgs).GetHashCode(); + + /// + /// 初始化加载场景更新事件的新实例。 + /// + public LoadSceneUpdateEventArgs() + { + SceneAssetName = null; + Progress = 0f; + UserData = null; + } + + /// + /// 获取加载场景更新事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取加载场景进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建加载场景更新事件。 + /// + /// 内部事件。 + /// 创建的加载场景更新事件。 + public static LoadSceneUpdateEventArgs Create(GameFramework.Scene.LoadSceneUpdateEventArgs e) + { + LoadSceneUpdateEventArgs loadSceneUpdateEventArgs = ReferencePool.Acquire(); + loadSceneUpdateEventArgs.SceneAssetName = e.SceneAssetName; + loadSceneUpdateEventArgs.Progress = e.Progress; + loadSceneUpdateEventArgs.UserData = e.UserData; + return loadSceneUpdateEventArgs; + } + + /// + /// 清理加载场景更新事件。 + /// + public override void Clear() + { + SceneAssetName = null; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneUpdateEventArgs.cs.meta new file mode 100644 index 0000000..cc6628c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/LoadSceneUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a8da542d25a6ee4b8e094e89c28bd7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/SceneComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/SceneComponent.cs new file mode 100644 index 0000000..9f1dd3e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/SceneComponent.cs @@ -0,0 +1,477 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +using GameFramework.Scene; +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace UnityGameFramework.Runtime +{ + /// + /// 场景组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Scene")] + public sealed class SceneComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + + private ISceneManager m_SceneManager = null; + private EventComponent m_EventComponent = null; + private readonly SortedDictionary m_SceneOrder = new SortedDictionary(StringComparer.Ordinal); + private Camera m_MainCamera = null; + private Scene m_GameFrameworkScene = default(Scene); + + [SerializeField] + private bool m_EnableLoadSceneUpdateEvent = true; + + [SerializeField] + private bool m_EnableLoadSceneDependencyAssetEvent = true; + + /// + /// 获取当前场景主摄像机。 + /// + public Camera MainCamera + { + get + { + return m_MainCamera; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_SceneManager = GameFrameworkEntry.GetModule(); + if (m_SceneManager == null) + { + Log.Fatal("Scene manager is invalid."); + return; + } + + m_SceneManager.LoadSceneSuccess += OnLoadSceneSuccess; + m_SceneManager.LoadSceneFailure += OnLoadSceneFailure; + + if (m_EnableLoadSceneUpdateEvent) + { + m_SceneManager.LoadSceneUpdate += OnLoadSceneUpdate; + } + + if (m_EnableLoadSceneDependencyAssetEvent) + { + m_SceneManager.LoadSceneDependencyAsset += OnLoadSceneDependencyAsset; + } + + m_SceneManager.UnloadSceneSuccess += OnUnloadSceneSuccess; + m_SceneManager.UnloadSceneFailure += OnUnloadSceneFailure; + + m_GameFrameworkScene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(GameEntry.GameFrameworkSceneId); + if (!m_GameFrameworkScene.IsValid()) + { + Log.Fatal("Game Framework scene is invalid."); + return; + } + } + + private void Start() + { + BaseComponent baseComponent = GameEntry.GetComponent(); + if (baseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (baseComponent.EditorResourceMode) + { + m_SceneManager.SetResourceManager(baseComponent.EditorResourceHelper); + } + else + { + m_SceneManager.SetResourceManager(GameFrameworkEntry.GetModule()); + } + } + + /// + /// 获取场景名称。 + /// + /// 场景资源名称。 + /// 场景名称。 + public static string GetSceneName(string sceneAssetName) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + Log.Error("Scene asset name is invalid."); + return null; + } + + int sceneNamePosition = sceneAssetName.LastIndexOf('/'); + if (sceneNamePosition + 1 >= sceneAssetName.Length) + { + Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); + return null; + } + + string sceneName = sceneAssetName.Substring(sceneNamePosition + 1); + sceneNamePosition = sceneName.LastIndexOf(".unity"); + if (sceneNamePosition > 0) + { + sceneName = sceneName.Substring(0, sceneNamePosition); + } + + return sceneName; + } + + /// + /// 获取场景是否已加载。 + /// + /// 场景资源名称。 + /// 场景是否已加载。 + public bool SceneIsLoaded(string sceneAssetName) + { + return m_SceneManager.SceneIsLoaded(sceneAssetName); + } + + /// + /// 获取已加载场景的资源名称。 + /// + /// 已加载场景的资源名称。 + public string[] GetLoadedSceneAssetNames() + { + return m_SceneManager.GetLoadedSceneAssetNames(); + } + + /// + /// 获取已加载场景的资源名称。 + /// + /// 已加载场景的资源名称。 + public void GetLoadedSceneAssetNames(List results) + { + m_SceneManager.GetLoadedSceneAssetNames(results); + } + + /// + /// 获取场景是否正在加载。 + /// + /// 场景资源名称。 + /// 场景是否正在加载。 + public bool SceneIsLoading(string sceneAssetName) + { + return m_SceneManager.SceneIsLoading(sceneAssetName); + } + + /// + /// 获取正在加载场景的资源名称。 + /// + /// 正在加载场景的资源名称。 + public string[] GetLoadingSceneAssetNames() + { + return m_SceneManager.GetLoadingSceneAssetNames(); + } + + /// + /// 获取正在加载场景的资源名称。 + /// + /// 正在加载场景的资源名称。 + public void GetLoadingSceneAssetNames(List results) + { + m_SceneManager.GetLoadingSceneAssetNames(results); + } + + /// + /// 获取场景是否正在卸载。 + /// + /// 场景资源名称。 + /// 场景是否正在卸载。 + public bool SceneIsUnloading(string sceneAssetName) + { + return m_SceneManager.SceneIsUnloading(sceneAssetName); + } + + /// + /// 获取正在卸载场景的资源名称。 + /// + /// 正在卸载场景的资源名称。 + public string[] GetUnloadingSceneAssetNames() + { + return m_SceneManager.GetUnloadingSceneAssetNames(); + } + + /// + /// 获取正在卸载场景的资源名称。 + /// + /// 正在卸载场景的资源名称。 + public void GetUnloadingSceneAssetNames(List results) + { + m_SceneManager.GetUnloadingSceneAssetNames(results); + } + + /// + /// 检查场景资源是否存在。 + /// + /// 要检查场景资源的名称。 + /// 场景资源是否存在。 + public bool HasScene(string sceneAssetName) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + Log.Error("Scene asset name is invalid."); + return false; + } + + if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) + { + Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); + return false; + } + + return m_SceneManager.HasScene(sceneAssetName); + } + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + public void LoadScene(string sceneAssetName) + { + LoadScene(sceneAssetName, DefaultPriority, null); + } + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 加载场景资源的优先级。 + public void LoadScene(string sceneAssetName, int priority) + { + LoadScene(sceneAssetName, priority, null); + } + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, object userData) + { + LoadScene(sceneAssetName, DefaultPriority, userData); + } + + /// + /// 加载场景。 + /// + /// 场景资源名称。 + /// 加载场景资源的优先级。 + /// 用户自定义数据。 + public void LoadScene(string sceneAssetName, int priority, object userData) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + Log.Error("Scene asset name is invalid."); + return; + } + + if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) + { + Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); + return; + } + + m_SceneManager.LoadScene(sceneAssetName, priority, userData); + } + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + public void UnloadScene(string sceneAssetName) + { + UnloadScene(sceneAssetName, null); + } + + /// + /// 卸载场景。 + /// + /// 场景资源名称。 + /// 用户自定义数据。 + public void UnloadScene(string sceneAssetName, object userData) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + Log.Error("Scene asset name is invalid."); + return; + } + + if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) + { + Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); + return; + } + + m_SceneManager.UnloadScene(sceneAssetName, userData); + m_SceneOrder.Remove(sceneAssetName); + } + + /// + /// 设置场景顺序。 + /// + /// 场景资源名称。 + /// 要设置的场景顺序。 + public void SetSceneOrder(string sceneAssetName, int sceneOrder) + { + if (string.IsNullOrEmpty(sceneAssetName)) + { + Log.Error("Scene asset name is invalid."); + return; + } + + if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) + { + Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); + return; + } + + if (SceneIsLoading(sceneAssetName)) + { + m_SceneOrder[sceneAssetName] = sceneOrder; + return; + } + + if (SceneIsLoaded(sceneAssetName)) + { + m_SceneOrder[sceneAssetName] = sceneOrder; + RefreshSceneOrder(); + return; + } + + Log.Error("Scene '{0}' is not loaded or loading.", sceneAssetName); + } + + /// + /// 刷新当前场景主摄像机。 + /// + public void RefreshMainCamera() + { + m_MainCamera = Camera.main; + } + + private void RefreshSceneOrder() + { + if (m_SceneOrder.Count > 0) + { + string maxSceneName = null; + int maxSceneOrder = 0; + foreach (KeyValuePair sceneOrder in m_SceneOrder) + { + if (SceneIsLoading(sceneOrder.Key)) + { + continue; + } + + if (maxSceneName == null) + { + maxSceneName = sceneOrder.Key; + maxSceneOrder = sceneOrder.Value; + continue; + } + + if (sceneOrder.Value > maxSceneOrder) + { + maxSceneName = sceneOrder.Key; + maxSceneOrder = sceneOrder.Value; + } + } + + if (maxSceneName == null) + { + SetActiveScene(m_GameFrameworkScene); + return; + } + + Scene scene = UnityEngine.SceneManagement.SceneManager.GetSceneByName(GetSceneName(maxSceneName)); + if (!scene.IsValid()) + { + Log.Error("Active scene '{0}' is invalid.", maxSceneName); + return; + } + + SetActiveScene(scene); + } + else + { + SetActiveScene(m_GameFrameworkScene); + } + } + + private void SetActiveScene(Scene activeScene) + { + Scene lastActiveScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); + if (lastActiveScene != activeScene) + { + UnityEngine.SceneManagement.SceneManager.SetActiveScene(activeScene); + m_EventComponent.Fire(this, ActiveSceneChangedEventArgs.Create(lastActiveScene, activeScene)); + } + + RefreshMainCamera(); + } + + private void OnLoadSceneSuccess(object sender, GameFramework.Scene.LoadSceneSuccessEventArgs e) + { + if (!m_SceneOrder.ContainsKey(e.SceneAssetName)) + { + m_SceneOrder.Add(e.SceneAssetName, 0); + } + + m_EventComponent.Fire(this, LoadSceneSuccessEventArgs.Create(e)); + RefreshSceneOrder(); + } + + private void OnLoadSceneFailure(object sender, GameFramework.Scene.LoadSceneFailureEventArgs e) + { + Log.Warning("Load scene failure, scene asset name '{0}', error message '{1}'.", e.SceneAssetName, e.ErrorMessage); + m_EventComponent.Fire(this, LoadSceneFailureEventArgs.Create(e)); + } + + private void OnLoadSceneUpdate(object sender, GameFramework.Scene.LoadSceneUpdateEventArgs e) + { + m_EventComponent.Fire(this, LoadSceneUpdateEventArgs.Create(e)); + } + + private void OnLoadSceneDependencyAsset(object sender, GameFramework.Scene.LoadSceneDependencyAssetEventArgs e) + { + m_EventComponent.Fire(this, LoadSceneDependencyAssetEventArgs.Create(e)); + } + + private void OnUnloadSceneSuccess(object sender, GameFramework.Scene.UnloadSceneSuccessEventArgs e) + { + m_EventComponent.Fire(this, UnloadSceneSuccessEventArgs.Create(e)); + m_SceneOrder.Remove(e.SceneAssetName); + RefreshSceneOrder(); + } + + private void OnUnloadSceneFailure(object sender, GameFramework.Scene.UnloadSceneFailureEventArgs e) + { + Log.Warning("Unload scene failure, scene asset name '{0}'.", e.SceneAssetName); + m_EventComponent.Fire(this, UnloadSceneFailureEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/SceneComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/SceneComponent.cs.meta new file mode 100644 index 0000000..a5781ac --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/SceneComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6242b052eb207b40b22e8fe77a315ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneFailureEventArgs.cs new file mode 100644 index 0000000..d71bbd7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneFailureEventArgs.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 卸载场景失败事件。 + /// + public sealed class UnloadSceneFailureEventArgs : GameEventArgs + { + /// + /// 加载场景失败事件编号。 + /// + public static readonly int EventId = typeof(UnloadSceneFailureEventArgs).GetHashCode(); + + /// + /// 初始化卸载场景失败事件的新实例。 + /// + public UnloadSceneFailureEventArgs() + { + SceneAssetName = null; + UserData = null; + } + + /// + /// 获取加载场景失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建卸载场景失败事件。 + /// + /// 内部事件。 + /// 创建的卸载场景失败事件。 + public static UnloadSceneFailureEventArgs Create(GameFramework.Scene.UnloadSceneFailureEventArgs e) + { + UnloadSceneFailureEventArgs unloadSceneFailureEventArgs = ReferencePool.Acquire(); + unloadSceneFailureEventArgs.SceneAssetName = e.SceneAssetName; + unloadSceneFailureEventArgs.UserData = e.UserData; + return unloadSceneFailureEventArgs; + } + + /// + /// 清理卸载场景失败事件。 + /// + public override void Clear() + { + SceneAssetName = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneFailureEventArgs.cs.meta new file mode 100644 index 0000000..52ea7e4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cfd40f0f395caf8498a268f03c5fea22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneSuccessEventArgs.cs new file mode 100644 index 0000000..b223277 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneSuccessEventArgs.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 卸载场景成功事件。 + /// + public sealed class UnloadSceneSuccessEventArgs : GameEventArgs + { + /// + /// 加载场景成功事件编号。 + /// + public static readonly int EventId = typeof(UnloadSceneSuccessEventArgs).GetHashCode(); + + /// + /// 初始化卸载场景成功事件的新实例。 + /// + public UnloadSceneSuccessEventArgs() + { + SceneAssetName = null; + UserData = null; + } + + /// + /// 获取加载场景成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取场景资源名称。 + /// + public string SceneAssetName + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建卸载场景成功事件。 + /// + /// 内部事件。 + /// 创建的卸载场景成功事件。 + public static UnloadSceneSuccessEventArgs Create(GameFramework.Scene.UnloadSceneSuccessEventArgs e) + { + UnloadSceneSuccessEventArgs unloadSceneSuccessEventArgs = ReferencePool.Acquire(); + unloadSceneSuccessEventArgs.SceneAssetName = e.SceneAssetName; + unloadSceneSuccessEventArgs.UserData = e.UserData; + return unloadSceneSuccessEventArgs; + } + + /// + /// 清理卸载场景成功事件。 + /// + public override void Clear() + { + SceneAssetName = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneSuccessEventArgs.cs.meta new file mode 100644 index 0000000..d53c73a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Scene/UnloadSceneSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c38ffda9363f4c64686888e44d017e1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting.meta new file mode 100644 index 0000000..5e1f342 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 92fcf07daa767d248bdf826a600dbf4a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSetting.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSetting.cs new file mode 100644 index 0000000..e8f62fe --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSetting.cs @@ -0,0 +1,313 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认游戏配置。 + /// + public sealed class DefaultSetting + { + private readonly SortedDictionary m_Settings = new SortedDictionary(StringComparer.Ordinal); + + /// + /// 初始化本地版本资源列表的新实例。 + /// + public DefaultSetting() + { + } + + /// + /// 获取游戏配置项数量。 + /// + public int Count + { + get + { + return m_Settings.Count; + } + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public string[] GetAllSettingNames() + { + int index = 0; + string[] allSettingNames = new string[m_Settings.Count]; + foreach (KeyValuePair setting in m_Settings) + { + allSettingNames[index++] = setting.Key; + } + + return allSettingNames; + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public void GetAllSettingNames(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair setting in m_Settings) + { + results.Add(setting.Key); + } + } + + /// + /// 检查是否存在指定游戏配置项。 + /// + /// 要检查游戏配置项的名称。 + /// 指定的游戏配置项是否存在。 + public bool HasSetting(string settingName) + { + return m_Settings.ContainsKey(settingName); + } + + /// + /// 移除指定游戏配置项。 + /// + /// 要移除游戏配置项的名称。 + /// 是否移除指定游戏配置项成功。 + public bool RemoveSetting(string settingName) + { + return m_Settings.Remove(settingName); + } + + /// + /// 清空所有游戏配置项。 + /// + public void RemoveAllSettings() + { + m_Settings.Clear(); + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的布尔值。 + public bool GetBool(string settingName) + { + string value = null; + if (!m_Settings.TryGetValue(settingName, out value)) + { + Log.Warning("Setting '{0}' is not exist.", settingName); + return false; + } + + return int.Parse(value) != 0; + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + public bool GetBool(string settingName, bool defaultValue) + { + string value = null; + if (!m_Settings.TryGetValue(settingName, out value)) + { + return defaultValue; + } + + return int.Parse(value) != 0; + } + + /// + /// 向指定游戏配置项写入布尔值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的布尔值。 + public void SetBool(string settingName, bool value) + { + m_Settings[settingName] = value ? "1" : "0"; + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的整数值。 + public int GetInt(string settingName) + { + string value = null; + if (!m_Settings.TryGetValue(settingName, out value)) + { + Log.Warning("Setting '{0}' is not exist.", settingName); + return 0; + } + + return int.Parse(value); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的整数值。 + public int GetInt(string settingName, int defaultValue) + { + string value = null; + if (!m_Settings.TryGetValue(settingName, out value)) + { + return defaultValue; + } + + return int.Parse(value); + } + + /// + /// 向指定游戏配置项写入整数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的整数值。 + public void SetInt(string settingName, int value) + { + m_Settings[settingName] = value.ToString(); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的浮点数值。 + public float GetFloat(string settingName) + { + string value = null; + if (!m_Settings.TryGetValue(settingName, out value)) + { + Log.Warning("Setting '{0}' is not exist.", settingName); + return 0f; + } + + return float.Parse(value); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + public float GetFloat(string settingName, float defaultValue) + { + string value = null; + if (!m_Settings.TryGetValue(settingName, out value)) + { + return defaultValue; + } + + return float.Parse(value); + } + + /// + /// 向指定游戏配置项写入浮点数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的浮点数值。 + public void SetFloat(string settingName, float value) + { + m_Settings[settingName] = value.ToString(); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的字符串值。 + public string GetString(string settingName) + { + string value = null; + if (!m_Settings.TryGetValue(settingName, out value)) + { + Log.Warning("Setting '{0}' is not exist.", settingName); + return null; + } + + return value; + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + public string GetString(string settingName, string defaultValue) + { + string value = null; + if (!m_Settings.TryGetValue(settingName, out value)) + { + return defaultValue; + } + + return value; + } + + /// + /// 向指定游戏配置项写入字符串值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的字符串值。 + public void SetString(string settingName, string value) + { + m_Settings[settingName] = value; + } + + /// + /// 序列化数据。 + /// + /// 目标流。 + public void Serialize(Stream stream) + { + using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) + { + binaryWriter.Write7BitEncodedInt32(m_Settings.Count); + foreach (KeyValuePair setting in m_Settings) + { + binaryWriter.Write(setting.Key); + binaryWriter.Write(setting.Value); + } + } + } + + /// + /// 反序列化数据。 + /// + /// 指定流。 + public void Deserialize(Stream stream) + { + m_Settings.Clear(); + using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8)) + { + int settingCount = binaryReader.Read7BitEncodedInt32(); + for (int i = 0; i < settingCount; i++) + { + m_Settings.Add(binaryReader.ReadString(), binaryReader.ReadString()); + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSetting.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSetting.cs.meta new file mode 100644 index 0000000..3d43c75 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSetting.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ab0df4276b162b41813b93d89dd9b6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingHelper.cs new file mode 100644 index 0000000..de64ab4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingHelper.cs @@ -0,0 +1,387 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认游戏配置辅助器。 + /// + public class DefaultSettingHelper : SettingHelperBase + { + private const string SettingFileName = "GameFrameworkSetting.dat"; + + private string m_FilePath = null; + private DefaultSetting m_Settings = null; + private DefaultSettingSerializer m_Serializer = null; + + /// + /// 获取游戏配置项数量。 + /// + public override int Count + { + get + { + return m_Settings != null ? m_Settings.Count : 0; + } + } + + /// + /// 获取游戏配置存储文件路径。 + /// + public string FilePath + { + get + { + return m_FilePath; + } + } + + /// + /// 获取游戏配置。 + /// + public DefaultSetting Setting + { + get + { + return m_Settings; + } + } + + /// + /// 获取游戏配置序列化器。 + /// + public DefaultSettingSerializer Serializer + { + get + { + return m_Serializer; + } + } + + /// + /// 加载游戏配置。 + /// + /// 是否加载游戏配置成功。 + public override bool Load() + { + try + { + if (!File.Exists(m_FilePath)) + { + return true; + } + + using (FileStream fileStream = new FileStream(m_FilePath, FileMode.Open, FileAccess.Read)) + { + m_Serializer.Deserialize(fileStream); + return true; + } + } + catch (Exception exception) + { + Log.Warning("Load settings failure with exception '{0}'.", exception); + return false; + } + } + + /// + /// 保存游戏配置。 + /// + /// 是否保存游戏配置成功。 + public override bool Save() + { + try + { + using (FileStream fileStream = new FileStream(m_FilePath, FileMode.Create, FileAccess.Write)) + { + return m_Serializer.Serialize(fileStream, m_Settings); + } + } + catch (Exception exception) + { + Log.Warning("Save settings failure with exception '{0}'.", exception); + return false; + } + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public override string[] GetAllSettingNames() + { + return m_Settings.GetAllSettingNames(); + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public override void GetAllSettingNames(List results) + { + m_Settings.GetAllSettingNames(results); + } + + /// + /// 检查是否存在指定游戏配置项。 + /// + /// 要检查游戏配置项的名称。 + /// 指定的游戏配置项是否存在。 + public override bool HasSetting(string settingName) + { + return m_Settings.HasSetting(settingName); + } + + /// + /// 移除指定游戏配置项。 + /// + /// 要移除游戏配置项的名称。 + /// 是否移除指定游戏配置项成功。 + public override bool RemoveSetting(string settingName) + { + return m_Settings.RemoveSetting(settingName); + } + + /// + /// 清空所有游戏配置项。 + /// + public override void RemoveAllSettings() + { + m_Settings.RemoveAllSettings(); + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的布尔值。 + public override bool GetBool(string settingName) + { + return m_Settings.GetBool(settingName); + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + public override bool GetBool(string settingName, bool defaultValue) + { + return m_Settings.GetBool(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入布尔值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的布尔值。 + public override void SetBool(string settingName, bool value) + { + m_Settings.SetBool(settingName, value); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的整数值。 + public override int GetInt(string settingName) + { + return m_Settings.GetInt(settingName); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的整数值。 + public override int GetInt(string settingName, int defaultValue) + { + return m_Settings.GetInt(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入整数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的整数值。 + public override void SetInt(string settingName, int value) + { + m_Settings.SetInt(settingName, value); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的浮点数值。 + public override float GetFloat(string settingName) + { + return m_Settings.GetFloat(settingName); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + public override float GetFloat(string settingName, float defaultValue) + { + return m_Settings.GetFloat(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入浮点数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的浮点数值。 + public override void SetFloat(string settingName, float value) + { + m_Settings.SetFloat(settingName, value); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的字符串值。 + public override string GetString(string settingName) + { + return m_Settings.GetString(settingName); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + public override string GetString(string settingName, string defaultValue) + { + return m_Settings.GetString(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入字符串值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的字符串值。 + public override void SetString(string settingName, string value) + { + m_Settings.SetString(settingName, value); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public override T GetObject(string settingName) + { + return Utility.Json.ToObject(GetString(settingName)); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public override object GetObject(Type objectType, string settingName) + { + return Utility.Json.ToObject(objectType, GetString(settingName)); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public override T GetObject(string settingName, T defaultObj) + { + string json = GetString(settingName, null); + if (json == null) + { + return defaultObj; + } + + return Utility.Json.ToObject(json); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public override object GetObject(Type objectType, string settingName, object defaultObj) + { + string json = GetString(settingName, null); + if (json == null) + { + return defaultObj; + } + + return Utility.Json.ToObject(objectType, json); + } + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入对象的类型。 + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public override void SetObject(string settingName, T obj) + { + SetString(settingName, Utility.Json.ToJson(obj)); + } + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public override void SetObject(string settingName, object obj) + { + SetString(settingName, Utility.Json.ToJson(obj)); + } + + private void Awake() + { + m_FilePath = Utility.Path.GetRegularPath(Path.Combine(Application.persistentDataPath, SettingFileName)); + m_Settings = new DefaultSetting(); + m_Serializer = new DefaultSettingSerializer(); + m_Serializer.RegisterSerializeCallback(0, SerializeDefaultSettingCallback); + m_Serializer.RegisterDeserializeCallback(0, DeserializeDefaultSettingCallback); + } + + private bool SerializeDefaultSettingCallback(Stream stream, DefaultSetting defaultSetting) + { + m_Settings.Serialize(stream); + return true; + } + + private DefaultSetting DeserializeDefaultSettingCallback(Stream stream) + { + m_Settings.Deserialize(stream); + return m_Settings; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingHelper.cs.meta new file mode 100644 index 0000000..3b0363c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43823f1cc63fb3b49a5659ca1e8a9628 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingSerializer.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingSerializer.cs new file mode 100644 index 0000000..6df6902 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingSerializer.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认游戏配置序列化器。 + /// + public sealed class DefaultSettingSerializer : GameFrameworkSerializer + { + private static readonly byte[] Header = new byte[] { (byte)'G', (byte)'F', (byte)'S' }; + + /// + /// 初始化默认游戏配置序列化器的新实例。 + /// + public DefaultSettingSerializer() + { + } + + /// + /// 获取默认游戏配置头标识。 + /// + /// 默认游戏配置头标识。 + protected override byte[] GetHeader() + { + return Header; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingSerializer.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingSerializer.cs.meta new file mode 100644 index 0000000..43089c3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/DefaultSettingSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68480f1e51ccec64eb66a1da9bd5cc99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/PlayerPrefsSettingHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/PlayerPrefsSettingHelper.cs new file mode 100644 index 0000000..feb8925 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/PlayerPrefsSettingHelper.cs @@ -0,0 +1,312 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// PlayerPrefs 游戏配置辅助器。 + /// + public class PlayerPrefsSettingHelper : SettingHelperBase + { + /// + /// 获取游戏配置项数量。 + /// + public override int Count + { + get + { + return -1; + } + } + + /// + /// 加载游戏配置。 + /// + /// 是否加载游戏配置成功。 + public override bool Load() + { + return true; + } + + /// + /// 保存游戏配置。 + /// + /// 是否保存游戏配置成功。 + public override bool Save() + { + PlayerPrefs.Save(); + return true; + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public override string[] GetAllSettingNames() + { + Log.Warning("GetAllSettingNames is not supported."); + return null; + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public override void GetAllSettingNames(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); + Log.Warning("GetAllSettingNames is not supported."); + } + + /// + /// 检查是否存在指定游戏配置项。 + /// + /// 要检查游戏配置项的名称。 + /// 指定的游戏配置项是否存在。 + public override bool HasSetting(string settingName) + { + return PlayerPrefs.HasKey(settingName); + } + + /// + /// 移除指定游戏配置项。 + /// + /// 要移除游戏配置项的名称。 + /// 是否移除指定游戏配置项成功。 + public override bool RemoveSetting(string settingName) + { + if (!PlayerPrefs.HasKey(settingName)) + { + return false; + } + + PlayerPrefs.DeleteKey(settingName); + return true; + } + + /// + /// 清空所有游戏配置项。 + /// + public override void RemoveAllSettings() + { + PlayerPrefs.DeleteAll(); + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的布尔值。 + public override bool GetBool(string settingName) + { + return PlayerPrefs.GetInt(settingName) != 0; + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + public override bool GetBool(string settingName, bool defaultValue) + { + return PlayerPrefs.GetInt(settingName, defaultValue ? 1 : 0) != 0; + } + + /// + /// 向指定游戏配置项写入布尔值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的布尔值。 + public override void SetBool(string settingName, bool value) + { + PlayerPrefs.SetInt(settingName, value ? 1 : 0); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的整数值。 + public override int GetInt(string settingName) + { + return PlayerPrefs.GetInt(settingName); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的整数值。 + public override int GetInt(string settingName, int defaultValue) + { + return PlayerPrefs.GetInt(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入整数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的整数值。 + public override void SetInt(string settingName, int value) + { + PlayerPrefs.SetInt(settingName, value); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的浮点数值。 + public override float GetFloat(string settingName) + { + return PlayerPrefs.GetFloat(settingName); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + public override float GetFloat(string settingName, float defaultValue) + { + return PlayerPrefs.GetFloat(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入浮点数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的浮点数值。 + public override void SetFloat(string settingName, float value) + { + PlayerPrefs.SetFloat(settingName, value); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的字符串值。 + public override string GetString(string settingName) + { + return PlayerPrefs.GetString(settingName); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + public override string GetString(string settingName, string defaultValue) + { + return PlayerPrefs.GetString(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入字符串值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的字符串值。 + public override void SetString(string settingName, string value) + { + PlayerPrefs.SetString(settingName, value); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public override T GetObject(string settingName) + { + return Utility.Json.ToObject(GetString(settingName)); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public override object GetObject(Type objectType, string settingName) + { + return Utility.Json.ToObject(objectType, GetString(settingName)); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public override T GetObject(string settingName, T defaultObj) + { + string json = GetString(settingName, null); + if (json == null) + { + return defaultObj; + } + + return Utility.Json.ToObject(json); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public override object GetObject(Type objectType, string settingName, object defaultObj) + { + string json = GetString(settingName, null); + if (json == null) + { + return defaultObj; + } + + return Utility.Json.ToObject(objectType, json); + } + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入对象的类型。 + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public override void SetObject(string settingName, T obj) + { + PlayerPrefs.SetString(settingName, Utility.Json.ToJson(obj)); + } + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public override void SetObject(string settingName, object obj) + { + PlayerPrefs.SetString(settingName, Utility.Json.ToJson(obj)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/PlayerPrefsSettingHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/PlayerPrefsSettingHelper.cs.meta new file mode 100644 index 0000000..f8ad200 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/PlayerPrefsSettingHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1323525062529f4b93e412ebda4914a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingComponent.cs new file mode 100644 index 0000000..43fcc59 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingComponent.cs @@ -0,0 +1,323 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Setting; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 游戏配置组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Setting")] + public sealed class SettingComponent : GameFrameworkComponent + { + private ISettingManager m_SettingManager = null; + + [SerializeField] + private string m_SettingHelperTypeName = "UnityGameFramework.Runtime.DefaultSettingHelper"; + + [SerializeField] + private SettingHelperBase m_CustomSettingHelper = null; + + /// + /// 获取游戏配置项数量。 + /// + public int Count + { + get + { + return m_SettingManager.Count; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_SettingManager = GameFrameworkEntry.GetModule(); + if (m_SettingManager == null) + { + Log.Fatal("Setting manager is invalid."); + return; + } + + SettingHelperBase settingHelper = Helper.CreateHelper(m_SettingHelperTypeName, m_CustomSettingHelper); + if (settingHelper == null) + { + Log.Error("Can not create setting helper."); + return; + } + + settingHelper.name = "Setting Helper"; + Transform transform = settingHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_SettingManager.SetSettingHelper(settingHelper); + } + + private void Start() + { + if (!m_SettingManager.Load()) + { + Log.Error("Load settings failure."); + } + } + + /// + /// 保存游戏配置。 + /// + public void Save() + { + m_SettingManager.Save(); + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public string[] GetAllSettingNames() + { + return m_SettingManager.GetAllSettingNames(); + } + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public void GetAllSettingNames(List results) + { + m_SettingManager.GetAllSettingNames(results); + } + + /// + /// 检查是否存在指定游戏配置项。 + /// + /// 要检查游戏配置项的名称。 + /// 指定的游戏配置项是否存在。 + public bool HasSetting(string settingName) + { + return m_SettingManager.HasSetting(settingName); + } + + /// + /// 移除指定游戏配置项。 + /// + /// 要移除游戏配置项的名称。 + public void RemoveSetting(string settingName) + { + m_SettingManager.RemoveSetting(settingName); + } + + /// + /// 清空所有游戏配置项。 + /// + public void RemoveAllSettings() + { + m_SettingManager.RemoveAllSettings(); + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的布尔值。 + public bool GetBool(string settingName) + { + return m_SettingManager.GetBool(settingName); + } + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + public bool GetBool(string settingName, bool defaultValue) + { + return m_SettingManager.GetBool(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入布尔值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的布尔值。 + public void SetBool(string settingName, bool value) + { + m_SettingManager.SetBool(settingName, value); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的整数值。 + public int GetInt(string settingName) + { + return m_SettingManager.GetInt(settingName); + } + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的整数值。 + public int GetInt(string settingName, int defaultValue) + { + return m_SettingManager.GetInt(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入整数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的整数值。 + public void SetInt(string settingName, int value) + { + m_SettingManager.SetInt(settingName, value); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的浮点数值。 + public float GetFloat(string settingName) + { + return m_SettingManager.GetFloat(settingName); + } + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + public float GetFloat(string settingName, float defaultValue) + { + return m_SettingManager.GetFloat(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入浮点数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的浮点数值。 + public void SetFloat(string settingName, float value) + { + m_SettingManager.SetFloat(settingName, value); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的字符串值。 + public string GetString(string settingName) + { + return m_SettingManager.GetString(settingName); + } + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + public string GetString(string settingName, string defaultValue) + { + return m_SettingManager.GetString(settingName, defaultValue); + } + + /// + /// 向指定游戏配置项写入字符串值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的字符串值。 + public void SetString(string settingName, string value) + { + m_SettingManager.SetString(settingName, value); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public T GetObject(string settingName) + { + return m_SettingManager.GetObject(settingName); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public object GetObject(Type objectType, string settingName) + { + return m_SettingManager.GetObject(objectType, settingName); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public T GetObject(string settingName, T defaultObj) + { + return m_SettingManager.GetObject(settingName, defaultObj); + } + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public object GetObject(Type objectType, string settingName, object defaultObj) + { + return m_SettingManager.GetObject(objectType, settingName, defaultObj); + } + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入对象的类型。 + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public void SetObject(string settingName, T obj) + { + m_SettingManager.SetObject(settingName, obj); + } + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public void SetObject(string settingName, object obj) + { + m_SettingManager.SetObject(settingName, obj); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingComponent.cs.meta new file mode 100644 index 0000000..06c91a0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c6e05d8d843cd94bb9aa026ed5dc517 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingHelperBase.cs new file mode 100644 index 0000000..dba6d19 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingHelperBase.cs @@ -0,0 +1,208 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Setting; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 游戏配置辅助器基类。 + /// + public abstract class SettingHelperBase : MonoBehaviour, ISettingHelper + { + /// + /// 获取游戏配置项数量。 + /// + public abstract int Count + { + get; + } + + /// + /// 加载游戏配置。 + /// + /// 是否加载游戏配置成功。 + public abstract bool Load(); + + /// + /// 保存游戏配置。 + /// + /// 是否保存游戏配置成功。 + public abstract bool Save(); + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public abstract string[] GetAllSettingNames(); + + /// + /// 获取所有游戏配置项的名称。 + /// + /// 所有游戏配置项的名称。 + public abstract void GetAllSettingNames(List results); + + /// + /// 检查是否存在指定游戏配置项。 + /// + /// 要检查游戏配置项的名称。 + /// 指定的游戏配置项是否存在。 + public abstract bool HasSetting(string settingName); + + /// + /// 移除指定游戏配置项。 + /// + /// 要移除游戏配置项的名称。 + /// 是否移除指定游戏配置项成功。 + public abstract bool RemoveSetting(string settingName); + + /// + /// 清空所有游戏配置项。 + /// + public abstract void RemoveAllSettings(); + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的布尔值。 + public abstract bool GetBool(string settingName); + + /// + /// 从指定游戏配置项中读取布尔值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的布尔值。 + public abstract bool GetBool(string settingName, bool defaultValue); + + /// + /// 向指定游戏配置项写入布尔值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的布尔值。 + public abstract void SetBool(string settingName, bool value); + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的整数值。 + public abstract int GetInt(string settingName); + + /// + /// 从指定游戏配置项中读取整数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的整数值。 + public abstract int GetInt(string settingName, int defaultValue); + + /// + /// 向指定游戏配置项写入整数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的整数值。 + public abstract void SetInt(string settingName, int value); + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的浮点数值。 + public abstract float GetFloat(string settingName); + + /// + /// 从指定游戏配置项中读取浮点数值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的浮点数值。 + public abstract float GetFloat(string settingName, float defaultValue); + + /// + /// 向指定游戏配置项写入浮点数值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的浮点数值。 + public abstract void SetFloat(string settingName, float value); + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 读取的字符串值。 + public abstract string GetString(string settingName); + + /// + /// 从指定游戏配置项中读取字符串值。 + /// + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认值。 + /// 读取的字符串值。 + public abstract string GetString(string settingName, string defaultValue); + + /// + /// 向指定游戏配置项写入字符串值。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的字符串值。 + public abstract void SetString(string settingName, string value); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public abstract T GetObject(string settingName); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 读取的对象。 + public abstract object GetObject(Type objectType, string settingName); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public abstract T GetObject(string settingName, T defaultObj); + + /// + /// 从指定游戏配置项中读取对象。 + /// + /// 要读取对象的类型。 + /// 要获取游戏配置项的名称。 + /// 当指定的游戏配置项不存在时,返回此默认对象。 + /// 读取的对象。 + public abstract object GetObject(Type objectType, string settingName, object defaultObj); + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入对象的类型。 + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public abstract void SetObject(string settingName, T obj); + + /// + /// 向指定游戏配置项写入对象。 + /// + /// 要写入游戏配置项的名称。 + /// 要写入的对象。 + public abstract void SetObject(string settingName, object obj); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingHelperBase.cs.meta new file mode 100644 index 0000000..723752a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Setting/SettingHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc7b39fb83dd08d46b2920dfbe6c4ca0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound.meta new file mode 100644 index 0000000..7672fc7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 633ea9a10bc00b44da15448d15f14ce1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundAgentHelper.cs new file mode 100644 index 0000000..ea4153d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundAgentHelper.cs @@ -0,0 +1,434 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Sound; +using System; +using System.Collections; +using UnityEngine; +using UnityEngine.Audio; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认声音代理辅助器。 + /// + public class DefaultSoundAgentHelper : SoundAgentHelperBase + { + private Transform m_CachedTransform = null; + private AudioSource m_AudioSource = null; + private EntityLogic m_BindingEntityLogic = null; + private float m_VolumeWhenPause = 0f; + private bool m_ApplicationPauseFlag = false; + private EventHandler m_ResetSoundAgentEventHandler = null; + + /// + /// 获取当前是否正在播放。 + /// + public override bool IsPlaying + { + get + { + return m_AudioSource.isPlaying; + } + } + + /// + /// 获取声音长度。 + /// + public override float Length + { + get + { + return m_AudioSource.clip != null ? m_AudioSource.clip.length : 0f; + } + } + + /// + /// 获取或设置播放位置。 + /// + public override float Time + { + get + { + return m_AudioSource.time; + } + set + { + m_AudioSource.time = value; + } + } + + /// + /// 获取或设置是否静音。 + /// + public override bool Mute + { + get + { + return m_AudioSource.mute; + } + set + { + m_AudioSource.mute = value; + } + } + + /// + /// 获取或设置是否循环播放。 + /// + public override bool Loop + { + get + { + return m_AudioSource.loop; + } + set + { + m_AudioSource.loop = value; + } + } + + /// + /// 获取或设置声音优先级。 + /// + public override int Priority + { + get + { + return 128 - m_AudioSource.priority; + } + set + { + m_AudioSource.priority = 128 - value; + } + } + + /// + /// 获取或设置音量大小。 + /// + public override float Volume + { + get + { + return m_AudioSource.volume; + } + set + { + m_AudioSource.volume = value; + } + } + + /// + /// 获取或设置声音音调。 + /// + public override float Pitch + { + get + { + return m_AudioSource.pitch; + } + set + { + m_AudioSource.pitch = value; + } + } + + /// + /// 获取或设置声音立体声声相。 + /// + public override float PanStereo + { + get + { + return m_AudioSource.panStereo; + } + set + { + m_AudioSource.panStereo = value; + } + } + + /// + /// 获取或设置声音空间混合量。 + /// + public override float SpatialBlend + { + get + { + return m_AudioSource.spatialBlend; + } + set + { + m_AudioSource.spatialBlend = value; + } + } + + /// + /// 获取或设置声音最大距离。 + /// + public override float MaxDistance + { + get + { + return m_AudioSource.maxDistance; + } + + set + { + m_AudioSource.maxDistance = value; + } + } + + /// + /// 获取或设置声音多普勒等级。 + /// + public override float DopplerLevel + { + get + { + return m_AudioSource.dopplerLevel; + } + set + { + m_AudioSource.dopplerLevel = value; + } + } + + /// + /// 获取或设置声音代理辅助器所在的混音组。 + /// + public override AudioMixerGroup AudioMixerGroup + { + get + { + return m_AudioSource.outputAudioMixerGroup; + } + set + { + m_AudioSource.outputAudioMixerGroup = value; + } + } + + /// + /// 重置声音代理事件。 + /// + public override event EventHandler ResetSoundAgent + { + add + { + m_ResetSoundAgentEventHandler += value; + } + remove + { + m_ResetSoundAgentEventHandler -= value; + } + } + + /// + /// 播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + public override void Play(float fadeInSeconds) + { + StopAllCoroutines(); + + m_AudioSource.Play(); + if (fadeInSeconds > 0f) + { + float volume = m_AudioSource.volume; + m_AudioSource.volume = 0f; + StartCoroutine(FadeToVolume(m_AudioSource, volume, fadeInSeconds)); + } + } + + /// + /// 停止播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + public override void Stop(float fadeOutSeconds) + { + StopAllCoroutines(); + + if (fadeOutSeconds > 0f && gameObject.activeInHierarchy) + { + StartCoroutine(StopCo(fadeOutSeconds)); + } + else + { + m_AudioSource.Stop(); + } + } + + /// + /// 暂停播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + public override void Pause(float fadeOutSeconds) + { + StopAllCoroutines(); + + m_VolumeWhenPause = m_AudioSource.volume; + if (fadeOutSeconds > 0f && gameObject.activeInHierarchy) + { + StartCoroutine(PauseCo(fadeOutSeconds)); + } + else + { + m_AudioSource.Pause(); + } + } + + /// + /// 恢复播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + public override void Resume(float fadeInSeconds) + { + StopAllCoroutines(); + + m_AudioSource.UnPause(); + if (fadeInSeconds > 0f) + { + StartCoroutine(FadeToVolume(m_AudioSource, m_VolumeWhenPause, fadeInSeconds)); + } + else + { + m_AudioSource.volume = m_VolumeWhenPause; + } + } + + /// + /// 重置声音代理辅助器。 + /// + public override void Reset() + { + m_CachedTransform.localPosition = Vector3.zero; + m_AudioSource.clip = null; + m_BindingEntityLogic = null; + m_VolumeWhenPause = 0f; + } + + /// + /// 设置声音资源。 + /// + /// 声音资源。 + /// 是否设置声音资源成功。 + public override bool SetSoundAsset(object soundAsset) + { + AudioClip audioClip = soundAsset as AudioClip; + if (audioClip == null) + { + return false; + } + + m_AudioSource.clip = audioClip; + return true; + } + + /// + /// 设置声音绑定的实体。 + /// + /// 声音绑定的实体。 + public override void SetBindingEntity(Entity bindingEntity) + { + m_BindingEntityLogic = bindingEntity.Logic; + if (m_BindingEntityLogic != null) + { + UpdateAgentPosition(); + return; + } + + if (m_ResetSoundAgentEventHandler != null) + { + ResetSoundAgentEventArgs resetSoundAgentEventArgs = ResetSoundAgentEventArgs.Create(); + m_ResetSoundAgentEventHandler(this, resetSoundAgentEventArgs); + ReferencePool.Release(resetSoundAgentEventArgs); + } + } + + /// + /// 设置声音所在的世界坐标。 + /// + /// 声音所在的世界坐标。 + public override void SetWorldPosition(Vector3 worldPosition) + { + m_CachedTransform.position = worldPosition; + } + + private void Awake() + { + m_CachedTransform = transform; + m_AudioSource = gameObject.GetOrAddComponent(); + m_AudioSource.playOnAwake = false; + m_AudioSource.rolloffMode = AudioRolloffMode.Custom; + } + + private void Update() + { + if (!m_ApplicationPauseFlag && !IsPlaying && m_AudioSource.clip != null && m_ResetSoundAgentEventHandler != null) + { + ResetSoundAgentEventArgs resetSoundAgentEventArgs = ResetSoundAgentEventArgs.Create(); + m_ResetSoundAgentEventHandler(this, resetSoundAgentEventArgs); + ReferencePool.Release(resetSoundAgentEventArgs); + return; + } + + if (m_BindingEntityLogic != null) + { + UpdateAgentPosition(); + } + } + + private void OnApplicationPause(bool pause) + { + m_ApplicationPauseFlag = pause; + } + + private void UpdateAgentPosition() + { + if (m_BindingEntityLogic.Available) + { + m_CachedTransform.position = m_BindingEntityLogic.CachedTransform.position; + return; + } + + if (m_ResetSoundAgentEventHandler != null) + { + ResetSoundAgentEventArgs resetSoundAgentEventArgs = ResetSoundAgentEventArgs.Create(); + m_ResetSoundAgentEventHandler(this, resetSoundAgentEventArgs); + ReferencePool.Release(resetSoundAgentEventArgs); + } + } + + private IEnumerator StopCo(float fadeOutSeconds) + { + yield return FadeToVolume(m_AudioSource, 0f, fadeOutSeconds); + m_AudioSource.Stop(); + } + + private IEnumerator PauseCo(float fadeOutSeconds) + { + yield return FadeToVolume(m_AudioSource, 0f, fadeOutSeconds); + m_AudioSource.Pause(); + } + + private IEnumerator FadeToVolume(AudioSource audioSource, float volume, float duration) + { + float time = 0f; + float originalVolume = audioSource.volume; + while (time < duration) + { + time += UnityEngine.Time.deltaTime; + audioSource.volume = Mathf.Lerp(originalVolume, volume, time / duration); + yield return new WaitForEndOfFrame(); + } + + audioSource.volume = volume; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundAgentHelper.cs.meta new file mode 100644 index 0000000..858633a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e41f05fd242c0d4fb2a5bd81ccca27c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundGroupHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundGroupHelper.cs new file mode 100644 index 0000000..c471fe0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundGroupHelper.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认声音组辅助器。 + /// + public class DefaultSoundGroupHelper : SoundGroupHelperBase + { + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundGroupHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundGroupHelper.cs.meta new file mode 100644 index 0000000..0415cc1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundGroupHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3b0f546449448c488d755cee4d701d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundHelper.cs new file mode 100644 index 0000000..5fe0ad3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundHelper.cs @@ -0,0 +1,36 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认声音辅助器。 + /// + public class DefaultSoundHelper : SoundHelperBase + { + private ResourceComponent m_ResourceComponent = null; + + /// + /// 释放声音资源。 + /// + /// 要释放的声音资源。 + public override void ReleaseSoundAsset(object soundAsset) + { + m_ResourceComponent.UnloadAsset(soundAsset); + } + + private void Start() + { + m_ResourceComponent = GameEntry.GetComponent(); + if (m_ResourceComponent == null) + { + Log.Fatal("Resource component is invalid."); + return; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundHelper.cs.meta new file mode 100644 index 0000000..de77801 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/DefaultSoundHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a025072340d72e4e8468db061720cde +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs new file mode 100644 index 0000000..ce113fa --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs @@ -0,0 +1,169 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Sound; + +namespace UnityGameFramework.Runtime +{ + /// + /// 播放声音时加载依赖资源事件。 + /// + public sealed class PlaySoundDependencyAssetEventArgs : GameEventArgs + { + /// + /// 播放声音时加载依赖资源事件编号。 + /// + public static readonly int EventId = typeof(PlaySoundDependencyAssetEventArgs).GetHashCode(); + + /// + /// 初始化播放声音时加载依赖资源事件的新实例。 + /// + public PlaySoundDependencyAssetEventArgs() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + BindingEntity = null; + UserData = null; + } + + /// + /// 获取播放声音时加载依赖资源事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取声音的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取声音资源名称。 + /// + public string SoundAssetName + { + get; + private set; + } + + /// + /// 获取声音组名称。 + /// + public string SoundGroupName + { + get; + private set; + } + + /// + /// 获取播放声音参数。 + /// + public PlaySoundParams PlaySoundParams + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取声音绑定的实体。 + /// + public Entity BindingEntity + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建播放声音时加载依赖资源事件。 + /// + /// 内部事件。 + /// 创建的播放声音时加载依赖资源事件。 + public static PlaySoundDependencyAssetEventArgs Create(GameFramework.Sound.PlaySoundDependencyAssetEventArgs e) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)e.UserData; + PlaySoundDependencyAssetEventArgs playSoundDependencyAssetEventArgs = ReferencePool.Acquire(); + playSoundDependencyAssetEventArgs.SerialId = e.SerialId; + playSoundDependencyAssetEventArgs.SoundAssetName = e.SoundAssetName; + playSoundDependencyAssetEventArgs.SoundGroupName = e.SoundGroupName; + playSoundDependencyAssetEventArgs.PlaySoundParams = e.PlaySoundParams; + playSoundDependencyAssetEventArgs.DependencyAssetName = e.DependencyAssetName; + playSoundDependencyAssetEventArgs.LoadedCount = e.LoadedCount; + playSoundDependencyAssetEventArgs.TotalCount = e.TotalCount; + playSoundDependencyAssetEventArgs.BindingEntity = playSoundInfo.BindingEntity; + playSoundDependencyAssetEventArgs.UserData = playSoundInfo.UserData; + return playSoundDependencyAssetEventArgs; + } + + /// + /// 清理播放声音时加载依赖资源事件。 + /// + public override void Clear() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + BindingEntity = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..ffdeb47 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82bc0837101049b47bca9dc4c0dfadb2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundFailureEventArgs.cs new file mode 100644 index 0000000..ca40405 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundFailureEventArgs.cs @@ -0,0 +1,158 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Sound; + +namespace UnityGameFramework.Runtime +{ + /// + /// 播放声音失败事件。 + /// + public sealed class PlaySoundFailureEventArgs : GameEventArgs + { + /// + /// 播放声音失败事件编号。 + /// + public static readonly int EventId = typeof(PlaySoundFailureEventArgs).GetHashCode(); + + /// + /// 初始化播放声音失败事件的新实例。 + /// + public PlaySoundFailureEventArgs() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + BindingEntity = null; + ErrorCode = 0; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取播放声音失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取声音的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取声音资源名称。 + /// + public string SoundAssetName + { + get; + private set; + } + + /// + /// 获取声音组名称。 + /// + public string SoundGroupName + { + get; + private set; + } + + /// + /// 获取播放声音参数。 + /// + public PlaySoundParams PlaySoundParams + { + get; + private set; + } + + /// + /// 获取声音绑定的实体。 + /// + public Entity BindingEntity + { + get; + private set; + } + + /// + /// 获取错误码。 + /// + public PlaySoundErrorCode ErrorCode + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建播放声音失败事件。 + /// + /// 内部事件。 + /// 创建的播放声音失败事件。 + public static PlaySoundFailureEventArgs Create(GameFramework.Sound.PlaySoundFailureEventArgs e) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)e.UserData; + PlaySoundFailureEventArgs playSoundFailureEventArgs = ReferencePool.Acquire(); + playSoundFailureEventArgs.SerialId = e.SerialId; + playSoundFailureEventArgs.SoundAssetName = e.SoundAssetName; + playSoundFailureEventArgs.SoundGroupName = e.SoundGroupName; + playSoundFailureEventArgs.PlaySoundParams = e.PlaySoundParams; + playSoundFailureEventArgs.BindingEntity = playSoundInfo.BindingEntity; + playSoundFailureEventArgs.ErrorCode = e.ErrorCode; + playSoundFailureEventArgs.ErrorMessage = e.ErrorMessage; + playSoundFailureEventArgs.UserData = playSoundInfo.UserData; + ReferencePool.Release(playSoundInfo); + return playSoundFailureEventArgs; + } + + /// + /// 清理播放声音失败事件。 + /// + public override void Clear() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + BindingEntity = null; + ErrorCode = 0; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundFailureEventArgs.cs.meta new file mode 100644 index 0000000..f7b5d1d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e72fc153d76f6e04e9b0036f95f75b3c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundInfo.cs new file mode 100644 index 0000000..76f7ced --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundInfo.cs @@ -0,0 +1,66 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + internal sealed class PlaySoundInfo : IReference + { + private Entity m_BindingEntity; + private Vector3 m_WorldPosition; + private object m_UserData; + + public PlaySoundInfo() + { + m_BindingEntity = null; + m_WorldPosition = Vector3.zero; + m_UserData = null; + } + + public Entity BindingEntity + { + get + { + return m_BindingEntity; + } + } + + public Vector3 WorldPosition + { + get + { + return m_WorldPosition; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + + public static PlaySoundInfo Create(Entity bindingEntity, Vector3 worldPosition, object userData) + { + PlaySoundInfo playSoundInfo = ReferencePool.Acquire(); + playSoundInfo.m_BindingEntity = bindingEntity; + playSoundInfo.m_WorldPosition = worldPosition; + playSoundInfo.m_UserData = userData; + return playSoundInfo; + } + + public void Clear() + { + m_BindingEntity = null; + m_WorldPosition = Vector3.zero; + m_UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundInfo.cs.meta new file mode 100644 index 0000000..d0c67c6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b0ac4f756eac174ba485dae0218a1a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundSuccessEventArgs.cs new file mode 100644 index 0000000..2e39bc9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundSuccessEventArgs.cs @@ -0,0 +1,134 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Sound; + +namespace UnityGameFramework.Runtime +{ + /// + /// 播放声音成功事件。 + /// + public sealed class PlaySoundSuccessEventArgs : GameEventArgs + { + /// + /// 播放声音成功事件编号。 + /// + public static readonly int EventId = typeof(PlaySoundSuccessEventArgs).GetHashCode(); + + /// + /// 初始化播放声音成功事件的新实例。 + /// + public PlaySoundSuccessEventArgs() + { + SerialId = 0; + SoundAssetName = null; + SoundAgent = null; + Duration = 0f; + BindingEntity = null; + UserData = null; + } + + /// + /// 获取播放声音成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取声音的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取声音资源名称。 + /// + public string SoundAssetName + { + get; + private set; + } + + /// + /// 获取用于播放的声音代理。 + /// + public ISoundAgent SoundAgent + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取声音绑定的实体。 + /// + public Entity BindingEntity + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建播放声音成功事件。 + /// + /// 内部事件。 + /// 创建的播放声音成功事件。 + public static PlaySoundSuccessEventArgs Create(GameFramework.Sound.PlaySoundSuccessEventArgs e) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)e.UserData; + PlaySoundSuccessEventArgs playSoundSuccessEventArgs = ReferencePool.Acquire(); + playSoundSuccessEventArgs.SerialId = e.SerialId; + playSoundSuccessEventArgs.SoundAssetName = e.SoundAssetName; + playSoundSuccessEventArgs.SoundAgent = e.SoundAgent; + playSoundSuccessEventArgs.Duration = e.Duration; + playSoundSuccessEventArgs.BindingEntity = playSoundInfo.BindingEntity; + playSoundSuccessEventArgs.UserData = playSoundInfo.UserData; + ReferencePool.Release(playSoundInfo); + return playSoundSuccessEventArgs; + } + + /// + /// 清理播放声音成功事件。 + /// + public override void Clear() + { + SerialId = 0; + SoundAssetName = null; + SoundAgent = null; + Duration = 0f; + BindingEntity = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundSuccessEventArgs.cs.meta new file mode 100644 index 0000000..c687fb3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ba92a17225be4a41a9824d08651692f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundUpdateEventArgs.cs new file mode 100644 index 0000000..35697ea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundUpdateEventArgs.cs @@ -0,0 +1,145 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.Sound; + +namespace UnityGameFramework.Runtime +{ + /// + /// 播放声音更新事件。 + /// + public sealed class PlaySoundUpdateEventArgs : GameEventArgs + { + /// + /// 播放声音更新事件编号。 + /// + public static readonly int EventId = typeof(PlaySoundUpdateEventArgs).GetHashCode(); + + /// + /// 初始化播放声音更新事件的新实例。 + /// + public PlaySoundUpdateEventArgs() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + Progress = 0f; + BindingEntity = null; + UserData = null; + } + + /// + /// 获取播放声音更新事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取声音的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取声音资源名称。 + /// + public string SoundAssetName + { + get; + private set; + } + + /// + /// 获取声音组名称。 + /// + public string SoundGroupName + { + get; + private set; + } + + /// + /// 获取播放声音参数。 + /// + public PlaySoundParams PlaySoundParams + { + get; + private set; + } + + /// + /// 获取加载声音进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取声音绑定的实体。 + /// + public Entity BindingEntity + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建播放声音更新事件。 + /// + /// 内部事件。 + /// 创建的播放声音更新事件。 + public static PlaySoundUpdateEventArgs Create(GameFramework.Sound.PlaySoundUpdateEventArgs e) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)e.UserData; + PlaySoundUpdateEventArgs playSoundUpdateEventArgs = ReferencePool.Acquire(); + playSoundUpdateEventArgs.SerialId = e.SerialId; + playSoundUpdateEventArgs.SoundAssetName = e.SoundAssetName; + playSoundUpdateEventArgs.SoundGroupName = e.SoundGroupName; + playSoundUpdateEventArgs.PlaySoundParams = e.PlaySoundParams; + playSoundUpdateEventArgs.Progress = e.Progress; + playSoundUpdateEventArgs.BindingEntity = playSoundInfo.BindingEntity; + playSoundUpdateEventArgs.UserData = playSoundInfo.UserData; + return playSoundUpdateEventArgs; + } + + /// + /// 清理播放声音更新事件。 + /// + public override void Clear() + { + SerialId = 0; + SoundAssetName = null; + SoundGroupName = null; + PlaySoundParams = null; + Progress = 0f; + BindingEntity = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundUpdateEventArgs.cs.meta new file mode 100644 index 0000000..99030a3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/PlaySoundUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: edad8ee73e896ab4cb00c9d37667699d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundAgentHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundAgentHelperBase.cs new file mode 100644 index 0000000..4cae2f5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundAgentHelperBase.cs @@ -0,0 +1,188 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Sound; +using System; +using UnityEngine; +using UnityEngine.Audio; + +namespace UnityGameFramework.Runtime +{ + /// + /// 声音代理辅助器基类。 + /// + public abstract class SoundAgentHelperBase : MonoBehaviour, ISoundAgentHelper + { + /// + /// 获取当前是否正在播放。 + /// + public abstract bool IsPlaying + { + get; + } + + /// + /// 获取声音长度。 + /// + public abstract float Length + { + get; + } + + /// + /// 获取或设置播放位置。 + /// + public abstract float Time + { + get; + set; + } + + /// + /// 获取或设置是否静音。 + /// + public abstract bool Mute + { + get; + set; + } + + /// + /// 获取或设置是否循环播放。 + /// + public abstract bool Loop + { + get; + set; + } + + /// + /// 获取或设置声音优先级。 + /// + public abstract int Priority + { + get; + set; + } + + /// + /// 获取或设置音量大小。 + /// + public abstract float Volume + { + get; + set; + } + + /// + /// 获取或设置声音音调。 + /// + public abstract float Pitch + { + get; + set; + } + + /// + /// 获取或设置声音立体声声相。 + /// + public abstract float PanStereo + { + get; + set; + } + + /// + /// 获取或设置声音空间混合量。 + /// + public abstract float SpatialBlend + { + get; + set; + } + + /// + /// 获取或设置声音最大距离。 + /// + public abstract float MaxDistance + { + get; + set; + } + + /// + /// 获取或设置声音多普勒等级。 + /// + public abstract float DopplerLevel + { + get; + set; + } + + /// + /// 获取或设置声音代理辅助器所在的混音组。 + /// + public abstract AudioMixerGroup AudioMixerGroup + { + get; + set; + } + + /// + /// 重置声音代理事件。 + /// + public abstract event EventHandler ResetSoundAgent; + + /// + /// 播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + public abstract void Play(float fadeInSeconds); + + /// + /// 停止播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + public abstract void Stop(float fadeOutSeconds); + + /// + /// 暂停播放声音。 + /// + /// 声音淡出时间,以秒为单位。 + public abstract void Pause(float fadeOutSeconds); + + /// + /// 恢复播放声音。 + /// + /// 声音淡入时间,以秒为单位。 + public abstract void Resume(float fadeInSeconds); + + /// + /// 重置声音代理辅助器。 + /// + public abstract void Reset(); + + /// + /// 设置声音资源。 + /// + /// 声音资源。 + /// 是否设置声音资源成功。 + public abstract bool SetSoundAsset(object soundAsset); + + /// + /// 设置声音绑定的实体。 + /// + /// 声音绑定的实体。 + public abstract void SetBindingEntity(Entity bindingEntity); + + /// + /// 设置声音所在的世界坐标。 + /// + /// 声音所在的世界坐标。 + public abstract void SetWorldPosition(Vector3 worldPosition); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundAgentHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundAgentHelperBase.cs.meta new file mode 100644 index 0000000..4d8c507 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundAgentHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67ec8ad22a10aae41a982dbdd607ceef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.SoundGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.SoundGroup.cs new file mode 100644 index 0000000..a9ec6bf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.SoundGroup.cs @@ -0,0 +1,74 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class SoundComponent : GameFrameworkComponent + { + [Serializable] + private sealed class SoundGroup + { + [SerializeField] + private string m_Name = null; + + [SerializeField] + private bool m_AvoidBeingReplacedBySamePriority = false; + + [SerializeField] + private bool m_Mute = false; + + [SerializeField, Range(0f, 1f)] + private float m_Volume = 1f; + + [SerializeField] + private int m_AgentHelperCount = 1; + + public string Name + { + get + { + return m_Name; + } + } + + public bool AvoidBeingReplacedBySamePriority + { + get + { + return m_AvoidBeingReplacedBySamePriority; + } + } + + public bool Mute + { + get + { + return m_Mute; + } + } + + public float Volume + { + get + { + return m_Volume; + } + } + + public int AgentHelperCount + { + get + { + return m_AgentHelperCount; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.SoundGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.SoundGroup.cs.meta new file mode 100644 index 0000000..fa377b6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.SoundGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50effaea047572b4fae5b3500f1fc109 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.cs new file mode 100644 index 0000000..fd24768 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.cs @@ -0,0 +1,692 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Resource; +#if UNITY_5_3 +using GameFramework.Scene; +#endif +using GameFramework.Sound; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Audio; +using UnityEngine.SceneManagement; + +namespace UnityGameFramework.Runtime +{ + /// + /// 声音组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Sound")] + public sealed partial class SoundComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + + private ISoundManager m_SoundManager = null; + private EventComponent m_EventComponent = null; + private AudioListener m_AudioListener = null; + + [SerializeField] + private bool m_EnablePlaySoundUpdateEvent = false; + + [SerializeField] + private bool m_EnablePlaySoundDependencyAssetEvent = false; + + [SerializeField] + private Transform m_InstanceRoot = null; + + [SerializeField] + private AudioMixer m_AudioMixer = null; + + [SerializeField] + private string m_SoundHelperTypeName = "UnityGameFramework.Runtime.DefaultSoundHelper"; + + [SerializeField] + private SoundHelperBase m_CustomSoundHelper = null; + + [SerializeField] + private string m_SoundGroupHelperTypeName = "UnityGameFramework.Runtime.DefaultSoundGroupHelper"; + + [SerializeField] + private SoundGroupHelperBase m_CustomSoundGroupHelper = null; + + [SerializeField] + private string m_SoundAgentHelperTypeName = "UnityGameFramework.Runtime.DefaultSoundAgentHelper"; + + [SerializeField] + private SoundAgentHelperBase m_CustomSoundAgentHelper = null; + + [SerializeField] + private SoundGroup[] m_SoundGroups = null; + + /// + /// 获取声音组数量。 + /// + public int SoundGroupCount + { + get + { + return m_SoundManager.SoundGroupCount; + } + } + + /// + /// 获取声音混响器。 + /// + public AudioMixer AudioMixer + { + get + { + return m_AudioMixer; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_SoundManager = GameFrameworkEntry.GetModule(); + if (m_SoundManager == null) + { + Log.Fatal("Sound manager is invalid."); + return; + } + + m_SoundManager.PlaySoundSuccess += OnPlaySoundSuccess; + m_SoundManager.PlaySoundFailure += OnPlaySoundFailure; + + if (m_EnablePlaySoundUpdateEvent) + { + m_SoundManager.PlaySoundUpdate += OnPlaySoundUpdate; + } + + if (m_EnablePlaySoundDependencyAssetEvent) + { + m_SoundManager.PlaySoundDependencyAsset += OnPlaySoundDependencyAsset; + } + + m_AudioListener = gameObject.GetOrAddComponent(); + +#if UNITY_5_4_OR_NEWER + SceneManager.sceneLoaded += OnSceneLoaded; + SceneManager.sceneUnloaded += OnSceneUnloaded; +#else + ISceneManager sceneManager = GameFrameworkEntry.GetModule(); + if (sceneManager == null) + { + Log.Fatal("Scene manager is invalid."); + return; + } + + sceneManager.LoadSceneSuccess += OnLoadSceneSuccess; + sceneManager.LoadSceneFailure += OnLoadSceneFailure; + sceneManager.UnloadSceneSuccess += OnUnloadSceneSuccess; + sceneManager.UnloadSceneFailure += OnUnloadSceneFailure; +#endif + } + + private void Start() + { + BaseComponent baseComponent = GameEntry.GetComponent(); + if (baseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (baseComponent.EditorResourceMode) + { + m_SoundManager.SetResourceManager(baseComponent.EditorResourceHelper); + } + else + { + m_SoundManager.SetResourceManager(GameFrameworkEntry.GetModule()); + } + + SoundHelperBase soundHelper = Helper.CreateHelper(m_SoundHelperTypeName, m_CustomSoundHelper); + if (soundHelper == null) + { + Log.Error("Can not create sound helper."); + return; + } + + soundHelper.name = "Sound Helper"; + Transform transform = soundHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_SoundManager.SetSoundHelper(soundHelper); + + if (m_InstanceRoot == null) + { + m_InstanceRoot = new GameObject("Sound Instances").transform; + m_InstanceRoot.SetParent(gameObject.transform); + m_InstanceRoot.localScale = Vector3.one; + } + + for (int i = 0; i < m_SoundGroups.Length; i++) + { + if (!AddSoundGroup(m_SoundGroups[i].Name, m_SoundGroups[i].AvoidBeingReplacedBySamePriority, m_SoundGroups[i].Mute, m_SoundGroups[i].Volume, m_SoundGroups[i].AgentHelperCount)) + { + Log.Warning("Add sound group '{0}' failure.", m_SoundGroups[i].Name); + continue; + } + } + } + + private void OnDestroy() + { +#if UNITY_5_4_OR_NEWER + SceneManager.sceneLoaded -= OnSceneLoaded; + SceneManager.sceneUnloaded -= OnSceneUnloaded; +#endif + } + + /// + /// 是否存在指定声音组。 + /// + /// 声音组名称。 + /// 指定声音组是否存在。 + public bool HasSoundGroup(string soundGroupName) + { + return m_SoundManager.HasSoundGroup(soundGroupName); + } + + /// + /// 获取指定声音组。 + /// + /// 声音组名称。 + /// 要获取的声音组。 + public ISoundGroup GetSoundGroup(string soundGroupName) + { + return m_SoundManager.GetSoundGroup(soundGroupName); + } + + /// + /// 获取所有声音组。 + /// + /// 所有声音组。 + public ISoundGroup[] GetAllSoundGroups() + { + return m_SoundManager.GetAllSoundGroups(); + } + + /// + /// 获取所有声音组。 + /// + /// 所有声音组。 + public void GetAllSoundGroups(List results) + { + m_SoundManager.GetAllSoundGroups(results); + } + + /// + /// 增加声音组。 + /// + /// 声音组名称。 + /// 声音代理辅助器数量。 + /// 是否增加声音组成功。 + public bool AddSoundGroup(string soundGroupName, int soundAgentHelperCount) + { + return AddSoundGroup(soundGroupName, false, false, 1f, soundAgentHelperCount); + } + + /// + /// 增加声音组。 + /// + /// 声音组名称。 + /// 声音组中的声音是否避免被同优先级声音替换。 + /// 声音组是否静音。 + /// 声音组音量。 + /// 声音代理辅助器数量。 + /// 是否增加声音组成功。 + public bool AddSoundGroup(string soundGroupName, bool soundGroupAvoidBeingReplacedBySamePriority, bool soundGroupMute, float soundGroupVolume, int soundAgentHelperCount) + { + if (m_SoundManager.HasSoundGroup(soundGroupName)) + { + return false; + } + + SoundGroupHelperBase soundGroupHelper = Helper.CreateHelper(m_SoundGroupHelperTypeName, m_CustomSoundGroupHelper, SoundGroupCount); + if (soundGroupHelper == null) + { + Log.Error("Can not create sound group helper."); + return false; + } + + soundGroupHelper.name = Utility.Text.Format("Sound Group - {0}", soundGroupName); + Transform transform = soundGroupHelper.transform; + transform.SetParent(m_InstanceRoot); + transform.localScale = Vector3.one; + + if (m_AudioMixer != null) + { + AudioMixerGroup[] audioMixerGroups = m_AudioMixer.FindMatchingGroups(Utility.Text.Format("Master/{0}", soundGroupName)); + if (audioMixerGroups.Length > 0) + { + soundGroupHelper.AudioMixerGroup = audioMixerGroups[0]; + } + else + { + soundGroupHelper.AudioMixerGroup = m_AudioMixer.FindMatchingGroups("Master")[0]; + } + } + + if (!m_SoundManager.AddSoundGroup(soundGroupName, soundGroupAvoidBeingReplacedBySamePriority, soundGroupMute, soundGroupVolume, soundGroupHelper)) + { + return false; + } + + for (int i = 0; i < soundAgentHelperCount; i++) + { + if (!AddSoundAgentHelper(soundGroupName, soundGroupHelper, i)) + { + return false; + } + } + + return true; + } + + /// + /// 获取所有正在加载声音的序列编号。 + /// + /// 所有正在加载声音的序列编号。 + public int[] GetAllLoadingSoundSerialIds() + { + return m_SoundManager.GetAllLoadingSoundSerialIds(); + } + + /// + /// 获取所有正在加载声音的序列编号。 + /// + /// 所有正在加载声音的序列编号。 + public void GetAllLoadingSoundSerialIds(List results) + { + m_SoundManager.GetAllLoadingSoundSerialIds(results); + } + + /// + /// 是否正在加载声音。 + /// + /// 声音序列编号。 + /// 是否正在加载声音。 + public bool IsLoadingSound(int serialId) + { + return m_SoundManager.IsLoadingSound(serialId); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName) + { + return PlaySound(soundAssetName, soundGroupName, DefaultPriority, null, null, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority) + { + return PlaySound(soundAssetName, soundGroupName, priority, null, null, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 播放声音参数。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, PlaySoundParams playSoundParams) + { + return PlaySound(soundAssetName, soundGroupName, DefaultPriority, playSoundParams, null, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 声音绑定的实体。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, Entity bindingEntity) + { + return PlaySound(soundAssetName, soundGroupName, DefaultPriority, null, bindingEntity, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 声音所在的世界坐标。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, Vector3 worldPosition) + { + return PlaySound(soundAssetName, soundGroupName, DefaultPriority, null, worldPosition, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 用户自定义数据。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, object userData) + { + return PlaySound(soundAssetName, soundGroupName, DefaultPriority, null, null, userData); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams) + { + return PlaySound(soundAssetName, soundGroupName, priority, playSoundParams, null, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 用户自定义数据。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams, object userData) + { + return PlaySound(soundAssetName, soundGroupName, priority, playSoundParams, null, userData); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 声音绑定的实体。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams, Entity bindingEntity) + { + return PlaySound(soundAssetName, soundGroupName, priority, playSoundParams, bindingEntity, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 声音绑定的实体。 + /// 用户自定义数据。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams, Entity bindingEntity, object userData) + { + return m_SoundManager.PlaySound(soundAssetName, soundGroupName, priority, playSoundParams, PlaySoundInfo.Create(bindingEntity, Vector3.zero, userData)); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 声音所在的世界坐标。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams, Vector3 worldPosition) + { + return PlaySound(soundAssetName, soundGroupName, priority, playSoundParams, worldPosition, null); + } + + /// + /// 播放声音。 + /// + /// 声音资源名称。 + /// 声音组名称。 + /// 加载声音资源的优先级。 + /// 播放声音参数。 + /// 声音所在的世界坐标。 + /// 用户自定义数据。 + /// 声音的序列编号。 + public int PlaySound(string soundAssetName, string soundGroupName, int priority, PlaySoundParams playSoundParams, Vector3 worldPosition, object userData) + { + return m_SoundManager.PlaySound(soundAssetName, soundGroupName, priority, playSoundParams, PlaySoundInfo.Create(null, worldPosition, userData)); + } + + /// + /// 停止播放声音。 + /// + /// 要停止播放声音的序列编号。 + /// 是否停止播放声音成功。 + public bool StopSound(int serialId) + { + return m_SoundManager.StopSound(serialId); + } + + /// + /// 停止播放声音。 + /// + /// 要停止播放声音的序列编号。 + /// 声音淡出时间,以秒为单位。 + /// 是否停止播放声音成功。 + public bool StopSound(int serialId, float fadeOutSeconds) + { + return m_SoundManager.StopSound(serialId, fadeOutSeconds); + } + + /// + /// 停止所有已加载的声音。 + /// + public void StopAllLoadedSounds() + { + m_SoundManager.StopAllLoadedSounds(); + } + + /// + /// 停止所有已加载的声音。 + /// + /// 声音淡出时间,以秒为单位。 + public void StopAllLoadedSounds(float fadeOutSeconds) + { + m_SoundManager.StopAllLoadedSounds(fadeOutSeconds); + } + + /// + /// 停止所有正在加载的声音。 + /// + public void StopAllLoadingSounds() + { + m_SoundManager.StopAllLoadingSounds(); + } + + /// + /// 暂停播放声音。 + /// + /// 要暂停播放声音的序列编号。 + public void PauseSound(int serialId) + { + m_SoundManager.PauseSound(serialId); + } + + /// + /// 暂停播放声音。 + /// + /// 要暂停播放声音的序列编号。 + /// 声音淡出时间,以秒为单位。 + public void PauseSound(int serialId, float fadeOutSeconds) + { + m_SoundManager.PauseSound(serialId, fadeOutSeconds); + } + + /// + /// 恢复播放声音。 + /// + /// 要恢复播放声音的序列编号。 + public void ResumeSound(int serialId) + { + m_SoundManager.ResumeSound(serialId); + } + + /// + /// 恢复播放声音。 + /// + /// 要恢复播放声音的序列编号。 + /// 声音淡入时间,以秒为单位。 + public void ResumeSound(int serialId, float fadeInSeconds) + { + m_SoundManager.ResumeSound(serialId, fadeInSeconds); + } + + /// + /// 增加声音代理辅助器。 + /// + /// 声音组名称。 + /// 声音组辅助器。 + /// 声音代理辅助器索引。 + /// 是否增加声音代理辅助器成功。 + private bool AddSoundAgentHelper(string soundGroupName, SoundGroupHelperBase soundGroupHelper, int index) + { + SoundAgentHelperBase soundAgentHelper = Helper.CreateHelper(m_SoundAgentHelperTypeName, m_CustomSoundAgentHelper, index); + if (soundAgentHelper == null) + { + Log.Error("Can not create sound agent helper."); + return false; + } + + soundAgentHelper.name = Utility.Text.Format("Sound Agent Helper - {0} - {1}", soundGroupName, index); + Transform transform = soundAgentHelper.transform; + transform.SetParent(soundGroupHelper.transform); + transform.localScale = Vector3.one; + + if (m_AudioMixer != null) + { + AudioMixerGroup[] audioMixerGroups = m_AudioMixer.FindMatchingGroups(Utility.Text.Format("Master/{0}/{1}", soundGroupName, index)); + if (audioMixerGroups.Length > 0) + { + soundAgentHelper.AudioMixerGroup = audioMixerGroups[0]; + } + else + { + soundAgentHelper.AudioMixerGroup = soundGroupHelper.AudioMixerGroup; + } + } + + m_SoundManager.AddSoundAgentHelper(soundGroupName, soundAgentHelper); + + return true; + } + + private void OnPlaySoundSuccess(object sender, GameFramework.Sound.PlaySoundSuccessEventArgs e) + { + PlaySoundInfo playSoundInfo = (PlaySoundInfo)e.UserData; + if (playSoundInfo != null) + { + SoundAgentHelperBase soundAgentHelper = (SoundAgentHelperBase)e.SoundAgent.Helper; + if (playSoundInfo.BindingEntity != null) + { + soundAgentHelper.SetBindingEntity(playSoundInfo.BindingEntity); + } + else + { + soundAgentHelper.SetWorldPosition(playSoundInfo.WorldPosition); + } + } + + m_EventComponent.Fire(this, PlaySoundSuccessEventArgs.Create(e)); + } + + private void OnPlaySoundFailure(object sender, GameFramework.Sound.PlaySoundFailureEventArgs e) + { + string logMessage = Utility.Text.Format("Play sound failure, asset name '{0}', sound group name '{1}', error code '{2}', error message '{3}'.", e.SoundAssetName, e.SoundGroupName, e.ErrorCode, e.ErrorMessage); + if (e.ErrorCode == PlaySoundErrorCode.IgnoredDueToLowPriority) + { + Log.Info(logMessage); + } + else + { + Log.Warning(logMessage); + } + + m_EventComponent.Fire(this, PlaySoundFailureEventArgs.Create(e)); + } + + private void OnPlaySoundUpdate(object sender, GameFramework.Sound.PlaySoundUpdateEventArgs e) + { + m_EventComponent.Fire(this, PlaySoundUpdateEventArgs.Create(e)); + } + + private void OnPlaySoundDependencyAsset(object sender, GameFramework.Sound.PlaySoundDependencyAssetEventArgs e) + { + m_EventComponent.Fire(this, PlaySoundDependencyAssetEventArgs.Create(e)); + } + + private void OnLoadSceneSuccess(object sender, GameFramework.Scene.LoadSceneSuccessEventArgs e) + { + RefreshAudioListener(); + } + + private void OnLoadSceneFailure(object sender, GameFramework.Scene.LoadSceneFailureEventArgs e) + { + RefreshAudioListener(); + } + + private void OnUnloadSceneSuccess(object sender, GameFramework.Scene.UnloadSceneSuccessEventArgs e) + { + RefreshAudioListener(); + } + + private void OnUnloadSceneFailure(object sender, GameFramework.Scene.UnloadSceneFailureEventArgs e) + { + RefreshAudioListener(); + } + + private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) + { + RefreshAudioListener(); + } + + private void OnSceneUnloaded(Scene scene) + { + RefreshAudioListener(); + } + + private void RefreshAudioListener() + { + m_AudioListener.enabled = FindObjectsOfType().Length <= 1; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.cs.meta new file mode 100644 index 0000000..198b47b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed5533de69c4e5a4dabc7c23fce1fa98 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundGroupHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundGroupHelperBase.cs new file mode 100644 index 0000000..fc07733 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundGroupHelperBase.cs @@ -0,0 +1,37 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Sound; +using UnityEngine; +using UnityEngine.Audio; + +namespace UnityGameFramework.Runtime +{ + /// + /// 声音组辅助器基类。 + /// + public abstract class SoundGroupHelperBase : MonoBehaviour, ISoundGroupHelper + { + [SerializeField] + private AudioMixerGroup m_AudioMixerGroup = null; + + /// + /// 获取或设置声音组辅助器所在的混音组。 + /// + public AudioMixerGroup AudioMixerGroup + { + get + { + return m_AudioMixerGroup; + } + set + { + m_AudioMixerGroup = value; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundGroupHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundGroupHelperBase.cs.meta new file mode 100644 index 0000000..93ed86b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundGroupHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b1aa5b8d134ac846a5a83fd661c9e92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundHelperBase.cs new file mode 100644 index 0000000..cc7d2c5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundHelperBase.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.Sound; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 声音辅助器基类。 + /// + public abstract class SoundHelperBase : MonoBehaviour, ISoundHelper + { + /// + /// 释放声音资源。 + /// + /// 要释放的声音资源。 + public abstract void ReleaseSoundAsset(object soundAsset); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundHelperBase.cs.meta new file mode 100644 index 0000000..b94f865 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Sound/SoundHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d63865838389abe428ccc3cee437a862 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI.meta new file mode 100644 index 0000000..79b74e3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 54c6b5aa3d448eb45a27b1f39e40db63 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/CloseUIFormCompleteEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/CloseUIFormCompleteEventArgs.cs new file mode 100644 index 0000000..90bcdea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/CloseUIFormCompleteEventArgs.cs @@ -0,0 +1,108 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; +using GameFramework.UI; + +namespace UnityGameFramework.Runtime +{ + /// + /// 关闭界面完成事件。 + /// + public sealed class CloseUIFormCompleteEventArgs : GameEventArgs + { + /// + /// 关闭界面完成事件编号。 + /// + public static readonly int EventId = typeof(CloseUIFormCompleteEventArgs).GetHashCode(); + + /// + /// 初始化关闭界面完成事件的新实例。 + /// + public CloseUIFormCompleteEventArgs() + { + SerialId = 0; + UIFormAssetName = null; + UIGroup = null; + UserData = null; + } + + /// + /// 获取关闭界面完成事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get; + private set; + } + + /// + /// 获取界面所属的界面组。 + /// + public IUIGroup UIGroup + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建关闭界面完成事件。 + /// + /// 内部事件。 + /// 创建的关闭界面完成事件。 + public static CloseUIFormCompleteEventArgs Create(GameFramework.UI.CloseUIFormCompleteEventArgs e) + { + CloseUIFormCompleteEventArgs closeUIFormCompleteEventArgs = ReferencePool.Acquire(); + closeUIFormCompleteEventArgs.SerialId = e.SerialId; + closeUIFormCompleteEventArgs.UIFormAssetName = e.UIFormAssetName; + closeUIFormCompleteEventArgs.UIGroup = e.UIGroup; + closeUIFormCompleteEventArgs.UserData = e.UserData; + return closeUIFormCompleteEventArgs; + } + + /// + /// 清理关闭界面完成事件。 + /// + public override void Clear() + { + SerialId = 0; + UIFormAssetName = null; + UIGroup = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/CloseUIFormCompleteEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/CloseUIFormCompleteEventArgs.cs.meta new file mode 100644 index 0000000..b3a1b2e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/CloseUIFormCompleteEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5119cf2f6bdac343a0b73ee3a0aa400 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIFormHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIFormHelper.cs new file mode 100644 index 0000000..d6395f4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIFormHelper.cs @@ -0,0 +1,74 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.UI; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认界面辅助器。 + /// + public class DefaultUIFormHelper : UIFormHelperBase + { + private ResourceComponent m_ResourceComponent = null; + + /// + /// 实例化界面。 + /// + /// 要实例化的界面资源。 + /// 实例化后的界面。 + public override object InstantiateUIForm(object uiFormAsset) + { + return Instantiate((Object)uiFormAsset); + } + + /// + /// 创建界面。 + /// + /// 界面实例。 + /// 界面所属的界面组。 + /// 用户自定义数据。 + /// 界面。 + public override IUIForm CreateUIForm(object uiFormInstance, IUIGroup uiGroup, object userData) + { + GameObject gameObject = uiFormInstance as GameObject; + if (gameObject == null) + { + Log.Error("UI form instance is invalid."); + return null; + } + + Transform transform = gameObject.transform; + transform.SetParent(((MonoBehaviour)uiGroup.Helper).transform); + transform.localScale = Vector3.one; + + return gameObject.GetOrAddComponent(); + } + + /// + /// 释放界面。 + /// + /// 要释放的界面资源。 + /// 要释放的界面实例。 + public override void ReleaseUIForm(object uiFormAsset, object uiFormInstance) + { + m_ResourceComponent.UnloadAsset(uiFormAsset); + Destroy((Object)uiFormInstance); + } + + private void Start() + { + m_ResourceComponent = GameEntry.GetComponent(); + if (m_ResourceComponent == null) + { + Log.Fatal("Resource component is invalid."); + return; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIFormHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIFormHelper.cs.meta new file mode 100644 index 0000000..f9debfc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIFormHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e0703eb62bea8944aa3fe2aa95df420a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIGroupHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIGroupHelper.cs new file mode 100644 index 0000000..ecee4e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIGroupHelper.cs @@ -0,0 +1,59 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; +using UnityEngine.UI; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认界面组辅助器。 + /// + public class DefaultUIGroupHelper : UIGroupHelperBase + { + ///// + ///// 设置界面组深度。 + ///// + ///// 界面组深度。 + //public override void SetDepth(int depth) + //{ + //} + public const int DepthFactor = 5000; + + private int m_Depth = 0; + private Canvas m_CachedCanvas = null; + + /// + /// 设置界面组深度。 + /// + /// 界面组深度。 + public override void SetDepth(int depth) + { + m_Depth = depth; + m_CachedCanvas.overrideSorting = true; + m_CachedCanvas.sortingOrder = DepthFactor * depth; + } + + private void Awake() + { + m_CachedCanvas = gameObject.GetOrAddComponent(); + gameObject.GetOrAddComponent(); + } + + private void Start() + { + m_CachedCanvas.overrideSorting = true; + m_CachedCanvas.sortingOrder = DepthFactor * m_Depth; + RectTransform transform = GetComponent(); + transform.anchorMin = Vector2.zero; + transform.anchorMax = Vector2.one; + transform.anchoredPosition = Vector2.zero; + transform.sizeDelta = Vector2.zero; + transform.localPosition = Vector3.zero; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIGroupHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIGroupHelper.cs.meta new file mode 100644 index 0000000..d6c9b1c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/DefaultUIGroupHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1a9d94772d704094da287912ccaf5b4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs new file mode 100644 index 0000000..e2f56fd --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs @@ -0,0 +1,155 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 打开界面时加载依赖资源事件。 + /// + public sealed class OpenUIFormDependencyAssetEventArgs : GameEventArgs + { + /// + /// 打开界面时加载依赖资源事件编号。 + /// + public static readonly int EventId = typeof(OpenUIFormDependencyAssetEventArgs).GetHashCode(); + + /// + /// 初始化打开界面时加载依赖资源事件的新实例。 + /// + public OpenUIFormDependencyAssetEventArgs() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + + /// + /// 获取打开界面时加载依赖资源事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get; + private set; + } + + /// + /// 获取界面组名称。 + /// + public string UIGroupName + { + get; + private set; + } + + /// + /// 获取是否暂停被覆盖的界面。 + /// + public bool PauseCoveredUIForm + { + get; + private set; + } + + /// + /// 获取被加载的依赖资源名称。 + /// + public string DependencyAssetName + { + get; + private set; + } + + /// + /// 获取当前已加载依赖资源数量。 + /// + public int LoadedCount + { + get; + private set; + } + + /// + /// 获取总共加载依赖资源数量。 + /// + public int TotalCount + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建打开界面时加载依赖资源事件。 + /// + /// 内部事件。 + /// 创建的打开界面时加载依赖资源事件。 + public static OpenUIFormDependencyAssetEventArgs Create(GameFramework.UI.OpenUIFormDependencyAssetEventArgs e) + { + OpenUIFormDependencyAssetEventArgs openUIFormDependencyAssetEventArgs = ReferencePool.Acquire(); + openUIFormDependencyAssetEventArgs.SerialId = e.SerialId; + openUIFormDependencyAssetEventArgs.UIFormAssetName = e.UIFormAssetName; + openUIFormDependencyAssetEventArgs.UIGroupName = e.UIGroupName; + openUIFormDependencyAssetEventArgs.PauseCoveredUIForm = e.PauseCoveredUIForm; + openUIFormDependencyAssetEventArgs.DependencyAssetName = e.DependencyAssetName; + openUIFormDependencyAssetEventArgs.LoadedCount = e.LoadedCount; + openUIFormDependencyAssetEventArgs.TotalCount = e.TotalCount; + openUIFormDependencyAssetEventArgs.UserData = e.UserData; + return openUIFormDependencyAssetEventArgs; + } + + /// + /// 清理打开界面时加载依赖资源事件。 + /// + public override void Clear() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + DependencyAssetName = null; + LoadedCount = 0; + TotalCount = 0; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs.meta new file mode 100644 index 0000000..a64998f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormDependencyAssetEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 29b2ea8e2fa48e143adc8e647e8103bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormFailureEventArgs.cs new file mode 100644 index 0000000..7b3e082 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormFailureEventArgs.cs @@ -0,0 +1,131 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 打开界面失败事件。 + /// + public sealed class OpenUIFormFailureEventArgs : GameEventArgs + { + /// + /// 打开界面失败事件编号。 + /// + public static readonly int EventId = typeof(OpenUIFormFailureEventArgs).GetHashCode(); + + /// + /// 初始化打开界面失败事件的新实例。 + /// + public OpenUIFormFailureEventArgs() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取打开界面失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get; + private set; + } + + /// + /// 获取界面组名称。 + /// + public string UIGroupName + { + get; + private set; + } + + /// + /// 获取是否暂停被覆盖的界面。 + /// + public bool PauseCoveredUIForm + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建打开界面失败事件。 + /// + /// 内部事件。 + /// 创建的打开界面失败事件。 + public static OpenUIFormFailureEventArgs Create(GameFramework.UI.OpenUIFormFailureEventArgs e) + { + OpenUIFormFailureEventArgs openUIFormFailureEventArgs = ReferencePool.Acquire(); + openUIFormFailureEventArgs.SerialId = e.SerialId; + openUIFormFailureEventArgs.UIFormAssetName = e.UIFormAssetName; + openUIFormFailureEventArgs.UIGroupName = e.UIGroupName; + openUIFormFailureEventArgs.PauseCoveredUIForm = e.PauseCoveredUIForm; + openUIFormFailureEventArgs.ErrorMessage = e.ErrorMessage; + openUIFormFailureEventArgs.UserData = e.UserData; + return openUIFormFailureEventArgs; + } + + /// + /// 清理打开界面失败事件。 + /// + public override void Clear() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormFailureEventArgs.cs.meta new file mode 100644 index 0000000..f61aa21 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7a6ba1b6a998054a893693b3ae07794 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormSuccessEventArgs.cs new file mode 100644 index 0000000..f3748ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormSuccessEventArgs.cs @@ -0,0 +1,96 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 打开界面成功事件。 + /// + public sealed class OpenUIFormSuccessEventArgs : GameEventArgs + { + /// + /// 打开界面成功事件编号。 + /// + /// GetHashCode返回一个唯一的值 + public static readonly int EventId = typeof(OpenUIFormSuccessEventArgs).GetHashCode(); + + /// + /// 初始化打开界面成功事件的新实例。 + /// + public OpenUIFormSuccessEventArgs() + { + UIForm = null; + Duration = 0f; + UserData = null; + } + + /// + /// 获取打开界面成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取打开成功的界面。 + /// + public UIForm UIForm + { + get; + private set; + } + + /// + /// 获取加载持续时间。 + /// + public float Duration + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建打开界面成功事件。 + /// + /// 内部事件。 + /// 创建的打开界面成功事件。 + public static OpenUIFormSuccessEventArgs Create(GameFramework.UI.OpenUIFormSuccessEventArgs e) + { + OpenUIFormSuccessEventArgs openUIFormSuccessEventArgs = ReferencePool.Acquire(); + openUIFormSuccessEventArgs.UIForm = (UIForm)e.UIForm; + openUIFormSuccessEventArgs.Duration = e.Duration; + openUIFormSuccessEventArgs.UserData = e.UserData; + return openUIFormSuccessEventArgs; + } + + /// + /// 清理打开界面成功事件。 + /// + public override void Clear() + { + UIForm = null; + Duration = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormSuccessEventArgs.cs.meta new file mode 100644 index 0000000..ee3f598 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 269e4d0709b02614d8509248981e82d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormUpdateEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormUpdateEventArgs.cs new file mode 100644 index 0000000..d11ef2b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormUpdateEventArgs.cs @@ -0,0 +1,131 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// 打开界面更新事件。 + /// + public sealed class OpenUIFormUpdateEventArgs : GameEventArgs + { + /// + /// 打开界面更新事件编号。 + /// + public static readonly int EventId = typeof(OpenUIFormUpdateEventArgs).GetHashCode(); + + /// + /// 初始化打开界面更新事件的新实例。 + /// + public OpenUIFormUpdateEventArgs() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + Progress = 0f; + UserData = null; + } + + /// + /// 获取打开界面更新事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get; + private set; + } + + /// + /// 获取界面组名称。 + /// + public string UIGroupName + { + get; + private set; + } + + /// + /// 获取是否暂停被覆盖的界面。 + /// + public bool PauseCoveredUIForm + { + get; + private set; + } + + /// + /// 获取打开界面进度。 + /// + public float Progress + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建打开界面更新事件。 + /// + /// 内部事件。 + /// 创建的打开界面更新事件。 + public static OpenUIFormUpdateEventArgs Create(GameFramework.UI.OpenUIFormUpdateEventArgs e) + { + OpenUIFormUpdateEventArgs openUIFormUpdateEventArgs = ReferencePool.Acquire(); + openUIFormUpdateEventArgs.SerialId = e.SerialId; + openUIFormUpdateEventArgs.UIFormAssetName = e.UIFormAssetName; + openUIFormUpdateEventArgs.UIGroupName = e.UIGroupName; + openUIFormUpdateEventArgs.PauseCoveredUIForm = e.PauseCoveredUIForm; + openUIFormUpdateEventArgs.Progress = e.Progress; + openUIFormUpdateEventArgs.UserData = e.UserData; + return openUIFormUpdateEventArgs; + } + + /// + /// 清理打开界面更新事件。 + /// + public override void Clear() + { + SerialId = 0; + UIFormAssetName = null; + UIGroupName = null; + PauseCoveredUIForm = false; + Progress = 0f; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormUpdateEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormUpdateEventArgs.cs.meta new file mode 100644 index 0000000..e0c7f2f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/OpenUIFormUpdateEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 314460751754f5d468a04af842439e8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.UIGroup.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.UIGroup.cs new file mode 100644 index 0000000..701e82a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.UIGroup.cs @@ -0,0 +1,41 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + public sealed partial class UIComponent : GameFrameworkComponent + { + [Serializable] + private sealed class UIGroup + { + [SerializeField] + private string m_Name = null; + + [SerializeField] + private int m_Depth = 0; + + public string Name + { + get + { + return m_Name; + } + } + + public int Depth + { + get + { + return m_Depth; + } + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.UIGroup.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.UIGroup.cs.meta new file mode 100644 index 0000000..6c87b82 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.UIGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f90c498e6b5e013499a1536555584b93 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.cs new file mode 100644 index 0000000..b6349f3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.cs @@ -0,0 +1,732 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.ObjectPool; +using GameFramework.Resource; +using GameFramework.UI; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 界面组件。 + /// + [DisallowMultipleComponent]//不允许添加多个组件 + [AddComponentMenu("Game Framework/UI")] + public sealed partial class UIComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + + private IUIManager m_UIManager = null; + private EventComponent m_EventComponent = null; + + private readonly List m_InternalUIFormResults = new List(); + + [SerializeField] + private bool m_EnableOpenUIFormSuccessEvent = true; + + [SerializeField] + private bool m_EnableOpenUIFormFailureEvent = true; + + [SerializeField] + private bool m_EnableOpenUIFormUpdateEvent = false; + + [SerializeField] + private bool m_EnableOpenUIFormDependencyAssetEvent = false; + + [SerializeField] + private bool m_EnableCloseUIFormCompleteEvent = true; + + [SerializeField] + private float m_InstanceAutoReleaseInterval = 60f; + + [SerializeField] + private int m_InstanceCapacity = 16; + + [SerializeField] + private float m_InstanceExpireTime = 60f; + + [SerializeField] + private int m_InstancePriority = 0; + + [SerializeField] + private Transform m_InstanceRoot = null; + + [SerializeField] + private string m_UIFormHelperTypeName = "UnityGameFramework.Runtime.DefaultUIFormHelper"; + + [SerializeField] + private UIFormHelperBase m_CustomUIFormHelper = null; + + [SerializeField] + private string m_UIGroupHelperTypeName = "UnityGameFramework.Runtime.DefaultUIGroupHelper"; + + [SerializeField] + private UIGroupHelperBase m_CustomUIGroupHelper = null; + + [SerializeField] + private UIGroup[] m_UIGroups = null; + + /// + /// 获取界面组数量。 + /// + public int UIGroupCount + { + get + { + return m_UIManager.UIGroupCount; + } + } + + /// + /// 获取或设置界面实例对象池自动释放可释放对象的间隔秒数。 + /// + public float InstanceAutoReleaseInterval + { + get + { + return m_UIManager.InstanceAutoReleaseInterval; + } + set + { + m_UIManager.InstanceAutoReleaseInterval = m_InstanceAutoReleaseInterval = value; + } + } + + /// + /// 获取或设置界面实例对象池的容量。 + /// + public int InstanceCapacity + { + get + { + return m_UIManager.InstanceCapacity; + } + set + { + m_UIManager.InstanceCapacity = m_InstanceCapacity = value; + } + } + + /// + /// 获取或设置界面实例对象池对象过期秒数。 + /// + public float InstanceExpireTime + { + get + { + return m_UIManager.InstanceExpireTime; + } + set + { + m_UIManager.InstanceExpireTime = m_InstanceExpireTime = value; + } + } + + /// + /// 获取或设置界面实例对象池的优先级。 + /// + public int InstancePriority + { + get + { + return m_UIManager.InstancePriority; + } + set + { + m_UIManager.InstancePriority = m_InstancePriority = value; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_UIManager = GameFrameworkEntry.GetModule(); + if (m_UIManager == null) + { + Log.Fatal("UI manager is invalid."); + return; + } + + if (m_EnableOpenUIFormSuccessEvent) + { + m_UIManager.OpenUIFormSuccess += OnOpenUIFormSuccess; + } + + m_UIManager.OpenUIFormFailure += OnOpenUIFormFailure; + + if (m_EnableOpenUIFormUpdateEvent) + { + m_UIManager.OpenUIFormUpdate += OnOpenUIFormUpdate; + } + + if (m_EnableOpenUIFormDependencyAssetEvent) + { + m_UIManager.OpenUIFormDependencyAsset += OnOpenUIFormDependencyAsset; + } + + if (m_EnableCloseUIFormCompleteEvent) + { + m_UIManager.CloseUIFormComplete += OnCloseUIFormComplete; + } + } + + private void Start() + { + BaseComponent baseComponent = GameEntry.GetComponent(); + if (baseComponent == null) + { + Log.Fatal("Base component is invalid."); + return; + } + + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (baseComponent.EditorResourceMode) + { + m_UIManager.SetResourceManager(baseComponent.EditorResourceHelper); + } + else + { + m_UIManager.SetResourceManager(GameFrameworkEntry.GetModule()); + } + + m_UIManager.SetObjectPoolManager(GameFrameworkEntry.GetModule()); + m_UIManager.InstanceAutoReleaseInterval = m_InstanceAutoReleaseInterval; + m_UIManager.InstanceCapacity = m_InstanceCapacity; + m_UIManager.InstanceExpireTime = m_InstanceExpireTime; + m_UIManager.InstancePriority = m_InstancePriority; + + UIFormHelperBase uiFormHelper = Helper.CreateHelper(m_UIFormHelperTypeName, m_CustomUIFormHelper); + if (uiFormHelper == null) + { + Log.Error("Can not create UI form helper."); + return; + } + + uiFormHelper.name = "UI Form Helper"; + Transform transform = uiFormHelper.transform; + transform.SetParent(this.transform); + transform.localScale = Vector3.one; + + m_UIManager.SetUIFormHelper(uiFormHelper); + + if (m_InstanceRoot == null) + { + m_InstanceRoot = new GameObject("UI Form Instances").transform; + m_InstanceRoot.SetParent(gameObject.transform); + m_InstanceRoot.localScale = Vector3.one; + } + + m_InstanceRoot.gameObject.layer = LayerMask.NameToLayer("UI"); + + for (int i = 0; i < m_UIGroups.Length; i++) + { + if (!AddUIGroup(m_UIGroups[i].Name, m_UIGroups[i].Depth)) + { + Log.Warning("Add UI group '{0}' failure.", m_UIGroups[i].Name); + continue; + } + } + } + + /// + /// 是否存在界面组。 + /// + /// 界面组名称。 + /// 是否存在界面组。 + public bool HasUIGroup(string uiGroupName) + { + return m_UIManager.HasUIGroup(uiGroupName); + } + + /// + /// 获取界面组。 + /// + /// 界面组名称。 + /// 要获取的界面组。 + public IUIGroup GetUIGroup(string uiGroupName) + { + return m_UIManager.GetUIGroup(uiGroupName); + } + + /// + /// 获取所有界面组。 + /// + /// 所有界面组。 + public IUIGroup[] GetAllUIGroups() + { + return m_UIManager.GetAllUIGroups(); + } + + /// + /// 获取所有界面组。 + /// + /// 所有界面组。 + public void GetAllUIGroups(List results) + { + m_UIManager.GetAllUIGroups(results); + } + + /// + /// 增加界面组。 + /// + /// 界面组名称。 + /// 是否增加界面组成功。 + public bool AddUIGroup(string uiGroupName) + { + return AddUIGroup(uiGroupName, 0); + } + + /// + /// 增加界面组。 + /// + /// 界面组名称。 + /// 界面组深度。 + /// 是否增加界面组成功。 + public bool AddUIGroup(string uiGroupName, int depth) + { + if (m_UIManager.HasUIGroup(uiGroupName)) + { + return false; + } + + UIGroupHelperBase uiGroupHelper = Helper.CreateHelper(m_UIGroupHelperTypeName, m_CustomUIGroupHelper, UIGroupCount); + if (uiGroupHelper == null) + { + Log.Error("Can not create UI group helper."); + return false; + } + + uiGroupHelper.name = Utility.Text.Format("UI Group - {0}", uiGroupName); + uiGroupHelper.gameObject.layer = LayerMask.NameToLayer("UI"); + Transform transform = uiGroupHelper.transform; + transform.SetParent(m_InstanceRoot); + transform.localScale = Vector3.one; + + return m_UIManager.AddUIGroup(uiGroupName, depth, uiGroupHelper); + } + + /// + /// 是否存在界面。 + /// + /// 界面序列编号。 + /// 是否存在界面。 + public bool HasUIForm(int serialId) + { + return m_UIManager.HasUIForm(serialId); + } + + /// + /// 是否存在界面。 + /// + /// 界面资源名称。 + /// 是否存在界面。 + public bool HasUIForm(string uiFormAssetName) + { + return m_UIManager.HasUIForm(uiFormAssetName); + } + + /// + /// 获取界面。 + /// + /// 界面序列编号。 + /// 要获取的界面。 + public UIForm GetUIForm(int serialId) + { + return (UIForm)m_UIManager.GetUIForm(serialId); + } + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public UIForm GetUIForm(string uiFormAssetName) + { + return (UIForm)m_UIManager.GetUIForm(uiFormAssetName); + } + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public UIForm[] GetUIForms(string uiFormAssetName) + { + IUIForm[] uiForms = m_UIManager.GetUIForms(uiFormAssetName); + UIForm[] uiFormImpls = new UIForm[uiForms.Length]; + for (int i = 0; i < uiForms.Length; i++) + { + uiFormImpls[i] = (UIForm)uiForms[i]; + } + + return uiFormImpls; + } + + /// + /// 获取界面。 + /// + /// 界面资源名称。 + /// 要获取的界面。 + public void GetUIForms(string uiFormAssetName, List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_UIManager.GetUIForms(uiFormAssetName, m_InternalUIFormResults); + foreach (IUIForm uiForm in m_InternalUIFormResults) + { + results.Add((UIForm)uiForm); + } + } + + /// + /// 获取所有已加载的界面。 + /// + /// 所有已加载的界面。 + public UIForm[] GetAllLoadedUIForms() + { + IUIForm[] uiForms = m_UIManager.GetAllLoadedUIForms(); + UIForm[] uiFormImpls = new UIForm[uiForms.Length]; + for (int i = 0; i < uiForms.Length; i++) + { + uiFormImpls[i] = (UIForm)uiForms[i]; + } + + return uiFormImpls; + } + + /// + /// 获取所有已加载的界面。 + /// + /// 所有已加载的界面。 + public void GetAllLoadedUIForms(List results) + { + if (results == null) + { + Log.Error("Results is invalid."); + return; + } + + results.Clear(); + m_UIManager.GetAllLoadedUIForms(m_InternalUIFormResults); + foreach (IUIForm uiForm in m_InternalUIFormResults) + { + results.Add((UIForm)uiForm); + } + } + + /// + /// 获取所有正在加载界面的序列编号。 + /// + /// 所有正在加载界面的序列编号。 + public int[] GetAllLoadingUIFormSerialIds() + { + return m_UIManager.GetAllLoadingUIFormSerialIds(); + } + + /// + /// 获取所有正在加载界面的序列编号。 + /// + /// 所有正在加载界面的序列编号。 + public void GetAllLoadingUIFormSerialIds(List results) + { + m_UIManager.GetAllLoadingUIFormSerialIds(results); + } + + /// + /// 是否正在加载界面。 + /// + /// 界面序列编号。 + /// 是否正在加载界面。 + public bool IsLoadingUIForm(int serialId) + { + return m_UIManager.IsLoadingUIForm(serialId); + } + + /// + /// 是否正在加载界面。 + /// + /// 界面资源名称。 + /// 是否正在加载界面。 + public bool IsLoadingUIForm(string uiFormAssetName) + { + return m_UIManager.IsLoadingUIForm(uiFormAssetName); + } + + /// + /// 是否是合法的界面。 + /// + /// 界面。 + /// 界面是否合法。 + public bool IsValidUIForm(UIForm uiForm) + { + return m_UIManager.IsValidUIForm(uiForm); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName) + { + return OpenUIForm(uiFormAssetName, uiGroupName, DefaultPriority, false, null); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority) + { + return OpenUIForm(uiFormAssetName, uiGroupName, priority, false, null); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm) + { + return OpenUIForm(uiFormAssetName, uiGroupName, DefaultPriority, pauseCoveredUIForm, null); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 用户自定义数据。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, object userData) + { + return OpenUIForm(uiFormAssetName, uiGroupName, DefaultPriority, false, userData); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 是否暂停被覆盖的界面。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm) + { + return OpenUIForm(uiFormAssetName, uiGroupName, priority, pauseCoveredUIForm, null); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 用户自定义数据。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, object userData) + { + return OpenUIForm(uiFormAssetName, uiGroupName, priority, false, userData); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 是否暂停被覆盖的界面。 + /// 用户自定义数据。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm, object userData) + { + return OpenUIForm(uiFormAssetName, uiGroupName, DefaultPriority, pauseCoveredUIForm, userData); + } + + /// + /// 打开界面。 + /// + /// 界面资源名称。 + /// 界面组名称。 + /// 加载界面资源的优先级。 + /// 是否暂停被覆盖的界面。 + /// 用户自定义数据。 + /// 界面的序列编号。 + public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm, object userData) + { + return m_UIManager.OpenUIForm(uiFormAssetName, uiGroupName, priority, pauseCoveredUIForm, userData); + } + + /// + /// 关闭界面。 + /// + /// 要关闭界面的序列编号。 + public void CloseUIForm(int serialId) + { + m_UIManager.CloseUIForm(serialId); + } + + /// + /// 关闭界面。 + /// + /// 要关闭界面的序列编号。 + /// 用户自定义数据。 + public void CloseUIForm(int serialId, object userData) + { + m_UIManager.CloseUIForm(serialId, userData); + } + + /// + /// 关闭界面。 + /// + /// 要关闭的界面。 + public void CloseUIForm(UIForm uiForm) + { + m_UIManager.CloseUIForm(uiForm); + } + + /// + /// 关闭界面。 + /// + /// 要关闭的界面。 + /// 用户自定义数据。 + public void CloseUIForm(UIForm uiForm, object userData) + { + m_UIManager.CloseUIForm(uiForm, userData); + } + + /// + /// 关闭所有已加载的界面。 + /// + public void CloseAllLoadedUIForms() + { + m_UIManager.CloseAllLoadedUIForms(); + } + + /// + /// 关闭所有已加载的界面。 + /// + /// 用户自定义数据。 + public void CloseAllLoadedUIForms(object userData) + { + m_UIManager.CloseAllLoadedUIForms(userData); + } + + /// + /// 关闭所有正在加载的界面。 + /// + public void CloseAllLoadingUIForms() + { + m_UIManager.CloseAllLoadingUIForms(); + } + + /// + /// 激活界面。 + /// + /// 要激活的界面。 + public void RefocusUIForm(UIForm uiForm) + { + m_UIManager.RefocusUIForm(uiForm); + } + + /// + /// 激活界面。 + /// + /// 要激活的界面。 + /// 用户自定义数据。 + public void RefocusUIForm(UIForm uiForm, object userData) + { + m_UIManager.RefocusUIForm(uiForm, userData); + } + + /// + /// 设置界面是否被加锁。 + /// + /// 要设置是否被加锁的界面。 + /// 界面是否被加锁。 + public void SetUIFormInstanceLocked(UIForm uiForm, bool locked) + { + if (uiForm == null) + { + Log.Warning("UI form is invalid."); + return; + } + + m_UIManager.SetUIFormInstanceLocked(uiForm.gameObject, locked); + } + + /// + /// 设置界面的优先级。 + /// + /// 要设置优先级的界面。 + /// 界面优先级。 + public void SetUIFormInstancePriority(UIForm uiForm, int priority) + { + if (uiForm == null) + { + Log.Warning("UI form is invalid."); + return; + } + + m_UIManager.SetUIFormInstancePriority(uiForm.gameObject, priority); + } + + private void OnOpenUIFormSuccess(object sender, GameFramework.UI.OpenUIFormSuccessEventArgs e) + { + m_EventComponent.Fire(this, OpenUIFormSuccessEventArgs.Create(e)); + //CustomDebug.Log("界面打开成功:" + e.UIForm.UIFormAssetName + "--" + e.UIForm.SerialId); + } + + private void OnOpenUIFormFailure(object sender, GameFramework.UI.OpenUIFormFailureEventArgs e) + { + Log.Warning("Open UI form failure, asset name '{0}', UI group name '{1}', pause covered UI form '{2}', error message '{3}'.", e.UIFormAssetName, e.UIGroupName, e.PauseCoveredUIForm, e.ErrorMessage); + if (m_EnableOpenUIFormFailureEvent) + { + m_EventComponent.Fire(this, OpenUIFormFailureEventArgs.Create(e)); + } + //CustomDebug.Log("界面打开失败:" + e.UIFormAssetName); + } + + private void OnOpenUIFormUpdate(object sender, GameFramework.UI.OpenUIFormUpdateEventArgs e) + { + m_EventComponent.Fire(this, OpenUIFormUpdateEventArgs.Create(e)); + } + + private void OnOpenUIFormDependencyAsset(object sender, GameFramework.UI.OpenUIFormDependencyAssetEventArgs e) + { + m_EventComponent.Fire(this, OpenUIFormDependencyAssetEventArgs.Create(e)); + } + + private void OnCloseUIFormComplete(object sender, GameFramework.UI.CloseUIFormCompleteEventArgs e) + { + m_EventComponent.Fire(this, CloseUIFormCompleteEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.cs.meta new file mode 100644 index 0000000..61af6f1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a1ef15380caaed42b55022cadc93649 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIForm.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIForm.cs new file mode 100644 index 0000000..d41845b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIForm.cs @@ -0,0 +1,305 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.UI; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 界面。 + /// + public sealed class UIForm : MonoBehaviour, IUIForm + { + private int m_SerialId; + private string m_UIFormAssetName; + private IUIGroup m_UIGroup; + private int m_DepthInUIGroup; + private bool m_PauseCoveredUIForm; + private UIFormLogic m_UIFormLogic; + + /// + /// 获取界面序列编号。 + /// + public int SerialId + { + get + { + return m_SerialId; + } + } + + /// + /// 获取界面资源名称。 + /// + public string UIFormAssetName + { + get + { + return m_UIFormAssetName; + } + } + + /// + /// 获取界面实例。 + /// + public object Handle + { + get + { + return gameObject; + } + } + + /// + /// 获取界面所属的界面组。 + /// + public IUIGroup UIGroup + { + get + { + return m_UIGroup; + } + } + + /// + /// 获取界面深度。 + /// + public int DepthInUIGroup + { + get + { + return m_DepthInUIGroup; + } + } + + /// + /// 获取是否暂停被覆盖的界面。 + /// + public bool PauseCoveredUIForm + { + get + { + return m_PauseCoveredUIForm; + } + } + + /// + /// 获取界面逻辑。 + /// + public UIFormLogic Logic + { + get + { + return m_UIFormLogic; + } + } + + /// + /// 初始化界面。 + /// + /// 界面序列编号。 + /// 界面资源名称。 + /// 界面所处的界面组。 + /// 是否暂停被覆盖的界面。 + /// 是否是新实例。 + /// 用户自定义数据。 + public void OnInit(int serialId, string uiFormAssetName, IUIGroup uiGroup, bool pauseCoveredUIForm, bool isNewInstance, object userData) + { + m_SerialId = serialId; + m_UIFormAssetName = uiFormAssetName; + m_UIGroup = uiGroup; + m_DepthInUIGroup = 0; + m_PauseCoveredUIForm = pauseCoveredUIForm; + + if (!isNewInstance) + { + return; + } + + m_UIFormLogic = GetComponent(); + if (m_UIFormLogic == null) + { + Log.Error("UI form '{0}' can not get UI form logic.", uiFormAssetName); + return; + } + + try + { + m_UIFormLogic.OnInit(userData); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnInit with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面回收。 + /// + public void OnRecycle() + { + try + { + m_UIFormLogic.OnRecycle(); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnRecycle with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + + m_SerialId = 0; + m_DepthInUIGroup = 0; + m_PauseCoveredUIForm = true; + } + + /// + /// 界面打开。 + /// + /// 用户自定义数据。 + public void OnOpen(object userData) + { + try + { + m_UIFormLogic.OnOpen(userData); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnOpen with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面关闭。 + /// + /// 是否是关闭界面管理器时触发。 + /// 用户自定义数据。 + public void OnClose(bool isShutdown, object userData) + { + try + { + m_UIFormLogic.OnClose(isShutdown, userData); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnClose with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面暂停。 + /// + public void OnPause() + { + try + { + m_UIFormLogic.OnPause(); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnPause with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面暂停恢复。 + /// + public void OnResume() + { + try + { + m_UIFormLogic.OnResume(); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnResume with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面遮挡。 + /// + public void OnCover() + { + try + { + m_UIFormLogic.OnCover(); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnCover with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面遮挡恢复。 + /// + public void OnReveal() + { + try + { + m_UIFormLogic.OnReveal(); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnReveal with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面激活。 + /// + /// 用户自定义数据。 + public void OnRefocus(object userData) + { + try + { + m_UIFormLogic.OnRefocus(userData); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnRefocus with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + try + { + m_UIFormLogic.OnUpdate(elapseSeconds, realElapseSeconds); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnUpdate with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + + /// + /// 界面深度改变。 + /// + /// 界面组深度。 + /// 界面在界面组中的深度。 + public void OnDepthChanged(int uiGroupDepth, int depthInUIGroup) + { + m_DepthInUIGroup = depthInUIGroup; + try + { + m_UIFormLogic.OnDepthChanged(uiGroupDepth, depthInUIGroup); + } + catch (Exception exception) + { + Log.Error("UI form '[{0}]{1}' OnDepthChanged with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIForm.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIForm.cs.meta new file mode 100644 index 0000000..94042ec --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIForm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f627c32af5133a24f829e711fafe42fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormHelperBase.cs new file mode 100644 index 0000000..f1cd5a6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormHelperBase.cs @@ -0,0 +1,41 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.UI; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 界面辅助器基类。 + /// + public abstract class UIFormHelperBase : MonoBehaviour, IUIFormHelper + { + /// + /// 实例化界面。 + /// + /// 要实例化的界面资源。 + /// 实例化后的界面。 + public abstract object InstantiateUIForm(object uiFormAsset); + + /// + /// 创建界面。 + /// + /// 界面实例。 + /// 界面所属的界面组。 + /// 用户自定义数据。 + /// 界面。 + public abstract IUIForm CreateUIForm(object uiFormInstance, IUIGroup uiGroup, object userData); + + /// + /// 释放界面。 + /// + /// 要释放的界面资源。 + /// 要释放的界面实例。 + public abstract void ReleaseUIForm(object uiFormAsset, object uiFormInstance); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormHelperBase.cs.meta new file mode 100644 index 0000000..11576a0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a33f1f48cf25a4a44bd85661139f76ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormLogic.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormLogic.cs new file mode 100644 index 0000000..6fe5946 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormLogic.cs @@ -0,0 +1,207 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 界面逻辑基类。 + /// + public abstract class UIFormLogic : MonoBehaviour + { + private bool m_Available = false; + private bool m_Visible = false; + private UIForm m_UIForm = null; + private Transform m_CachedTransform = null; + private int m_OriginalLayer = 0; + + /// + /// 获取界面。 + /// + public UIForm UIForm + { + get + { + return m_UIForm; + } + } + + /// + /// 获取或设置界面名称。 + /// + public string Name + { + get + { + return gameObject.name; + } + set + { + gameObject.name = value; + } + } + + /// + /// 获取界面是否可用。 + /// + public bool Available + { + get + { + return m_Available; + } + } + + /// + /// 获取或设置界面是否可见。 + /// + public bool Visible + { + get + { + return m_Available && m_Visible; + } + set + { + if (!m_Available) + { + Log.Warning("UI form '{0}' is not available.", Name); + return; + } + + if (m_Visible == value) + { + return; + } + + m_Visible = value; + InternalSetVisible(value); + } + } + + /// + /// 获取已缓存的 Transform。 + /// + public Transform CachedTransform + { + get + { + return m_CachedTransform; + } + } + + /// + /// 界面初始化。 + /// + /// 用户自定义数据。 + protected internal virtual void OnInit(object userData) + { + if (m_CachedTransform == null) + { + m_CachedTransform = transform; + } + + m_UIForm = GetComponent(); + m_OriginalLayer = gameObject.layer; + } + + /// + /// 界面回收。 + /// + protected internal virtual void OnRecycle() + { + } + + /// + /// 界面打开。 + /// + /// 用户自定义数据。 + protected internal virtual void OnOpen(object userData) + { + m_Available = true; + Visible = true; + } + + /// + /// 界面关闭。 + /// + /// 是否是关闭界面管理器时触发。 + /// 用户自定义数据。 + protected internal virtual void OnClose(bool isShutdown, object userData) + { + gameObject.SetLayerRecursively(m_OriginalLayer); + Visible = false; + m_Available = false; + } + + /// + /// 界面暂停。 + /// + protected internal virtual void OnPause() + { + Visible = false; + } + + /// + /// 界面暂停恢复。 + /// + protected internal virtual void OnResume() + { + Visible = true; + } + + /// + /// 界面遮挡。 + /// + protected internal virtual void OnCover() + { + } + + /// + /// 界面遮挡恢复。 + /// + protected internal virtual void OnReveal() + { + } + + /// + /// 界面激活。 + /// + /// 用户自定义数据。 + protected internal virtual void OnRefocus(object userData) + { + } + + /// + /// 界面轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + protected internal virtual void OnUpdate(float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 界面深度改变。 + /// + /// 界面组深度。 + /// 界面在界面组中的深度。 + protected internal virtual void OnDepthChanged(int uiGroupDepth, int depthInUIGroup) + { + } + + /// + /// 设置界面的可见性。 + /// + /// 界面的可见性。 + protected virtual void InternalSetVisible(bool visible) + { + gameObject.SetActive(visible); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormLogic.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormLogic.cs.meta new file mode 100644 index 0000000..5c483ab --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIFormLogic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0293f872933ead649893db69d7f4e2ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIGroupHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIGroupHelperBase.cs new file mode 100644 index 0000000..a11bc4c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIGroupHelperBase.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.UI; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 界面组辅助器基类。 + /// + public abstract class UIGroupHelperBase : MonoBehaviour, IUIGroupHelper + { + /// + /// 设置界面组深度。 + /// + /// 界面组深度。 + public abstract void SetDepth(int depth); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIGroupHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIGroupHelperBase.cs.meta new file mode 100644 index 0000000..db56957 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIGroupHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02539b9fb3e30984ea1707e6f87bc3d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIIntKey.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIIntKey.cs new file mode 100644 index 0000000..0ffdd1d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIIntKey.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 界面整型主键。 + /// + public sealed class UIIntKey : MonoBehaviour + { + [SerializeField] + private int m_Key = 0; + + /// + /// 获取或设置主键。 + /// + public int Key + { + get + { + return m_Key; + } + set + { + m_Key = value; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIIntKey.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIIntKey.cs.meta new file mode 100644 index 0000000..0cd4cfc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIIntKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 606f38525c5bccb4d9355c54a60746f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIStringKey.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIStringKey.cs new file mode 100644 index 0000000..cafe10d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIStringKey.cs @@ -0,0 +1,35 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 界面字符型主键。 + /// + public sealed class UIStringKey : MonoBehaviour + { + [SerializeField] + private string m_Key = null; + + /// + /// 获取或设置主键。 + /// + public string Key + { + get + { + return m_Key ?? string.Empty; + } + set + { + m_Key = value; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIStringKey.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIStringKey.cs.meta new file mode 100644 index 0000000..cf6f683 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UI/UIStringKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 087a56c75d247be4f8f7cf82ceb68e4b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UnityGameFramework.asmdef b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UnityGameFramework.asmdef new file mode 100644 index 0000000..b875c9d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UnityGameFramework.asmdef @@ -0,0 +1,16 @@ +{ + "name": "UnityGameFramework", + "rootNamespace": "", + "references": [ + "GameFramework" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UnityGameFramework.asmdef.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UnityGameFramework.asmdef.meta new file mode 100644 index 0000000..647e4e6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/UnityGameFramework.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 01b55c6a61e21dd4890790ede7b78e56 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility.meta new file mode 100644 index 0000000..da20d06 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d5515dfbdcfab2040b332669de5c9a8a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/BinaryExtension.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/BinaryExtension.cs new file mode 100644 index 0000000..2da4628 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/BinaryExtension.cs @@ -0,0 +1,197 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.IO; + +/// +/// 对 BinaryReader 和 BinaryWriter 的扩展方法。 +/// +public static class BinaryExtension +{ + private static readonly byte[] s_CachedBytes = new byte[byte.MaxValue + 1]; + + /// + /// 从二进制流读取编码后的 32 位有符号整数。 + /// + /// 要读取的二进制流。 + /// 读取的 32 位有符号整数。 + public static int Read7BitEncodedInt32(this BinaryReader binaryReader) + { + int value = 0; + int shift = 0; + byte b; + do + { + if (shift >= 35) + { + throw new GameFrameworkException("7 bit encoded int is invalid."); + } + + b = binaryReader.ReadByte(); + value |= (b & 0x7f) << shift; + shift += 7; + } while ((b & 0x80) != 0); + + return value; + } + + /// + /// 向二进制流写入编码后的 32 位有符号整数。 + /// + /// 要写入的二进制流。 + /// 要写入的 32 位有符号整数。 + public static void Write7BitEncodedInt32(this BinaryWriter binaryWriter, int value) + { + uint num = (uint)value; + while (num >= 0x80) + { + binaryWriter.Write((byte)(num | 0x80)); + num >>= 7; + } + + binaryWriter.Write((byte)num); + } + + /// + /// 从二进制流读取编码后的 32 位无符号整数。 + /// + /// 要读取的二进制流。 + /// 读取的 32 位无符号整数。 + public static uint Read7BitEncodedUInt32(this BinaryReader binaryReader) + { + return (uint)Read7BitEncodedInt32(binaryReader); + } + + /// + /// 向二进制流写入编码后的 32 位无符号整数。 + /// + /// 要写入的二进制流。 + /// 要写入的 32 位无符号整数。 + public static void Write7BitEncodedUInt32(this BinaryWriter binaryWriter, uint value) + { + Write7BitEncodedInt32(binaryWriter, (int)value); + } + + /// + /// 从二进制流读取编码后的 64 位有符号整数。 + /// + /// 要读取的二进制流。 + /// 读取的 64 位有符号整数。 + public static long Read7BitEncodedInt64(this BinaryReader binaryReader) + { + long value = 0L; + int shift = 0; + byte b; + do + { + if (shift >= 70) + { + throw new GameFrameworkException("7 bit encoded int is invalid."); + } + + b = binaryReader.ReadByte(); + value |= (b & 0x7fL) << shift; + shift += 7; + } while ((b & 0x80) != 0); + + return value; + } + + /// + /// 向二进制流写入编码后的 64 位有符号整数。 + /// + /// 要写入的二进制流。 + /// 要写入的 64 位有符号整数。 + public static void Write7BitEncodedInt64(this BinaryWriter binaryWriter, long value) + { + ulong num = (ulong)value; + while (num >= 0x80) + { + binaryWriter.Write((byte)(num | 0x80)); + num >>= 7; + } + + binaryWriter.Write((byte)num); + } + + /// + /// 从二进制流读取编码后的 64 位无符号整数。 + /// + /// 要读取的二进制流。 + /// 读取的 64 位无符号整数。 + public static ulong Read7BitEncodedUInt64(this BinaryReader binaryReader) + { + return (ulong)Read7BitEncodedInt64(binaryReader); + } + + /// + /// 向二进制流写入编码后的 64 位无符号整数。 + /// + /// 要写入的二进制流。 + /// 要写入的 64 位无符号整数。 + public static void Write7BitEncodedUInt64(this BinaryWriter binaryWriter, ulong value) + { + Write7BitEncodedInt64(binaryWriter, (long)value); + } + + /// + /// 从二进制流读取加密字符串。 + /// + /// 要读取的二进制流。 + /// 密钥数组。 + /// 读取的字符串。 + public static string ReadEncryptedString(this BinaryReader binaryReader, byte[] encryptBytes) + { + byte length = binaryReader.ReadByte(); + if (length <= 0) + { + return null; + } + + if (length > byte.MaxValue) + { + throw new GameFrameworkException("String is too long."); + } + + for (byte i = 0; i < length; i++) + { + s_CachedBytes[i] = binaryReader.ReadByte(); + } + + Utility.Encryption.GetSelfXorBytes(s_CachedBytes, 0, length, encryptBytes); + string value = Utility.Converter.GetString(s_CachedBytes, 0, length); + Array.Clear(s_CachedBytes, 0, length); + return value; + } + + /// + /// 向二进制流写入加密字符串。 + /// + /// 要写入的二进制流。 + /// 要写入的字符串。 + /// 密钥数组。 + public static void WriteEncryptedString(this BinaryWriter binaryWriter, string value, byte[] encryptBytes) + { + if (string.IsNullOrEmpty(value)) + { + binaryWriter.Write((byte)0); + return; + } + + int length = Utility.Converter.GetBytes(value, s_CachedBytes); + if (length > byte.MaxValue) + { + throw new GameFrameworkException(Utility.Text.Format("String '{0}' is too long.", value)); + } + + Utility.Encryption.GetSelfXorBytes(s_CachedBytes, encryptBytes); + binaryWriter.Write((byte)length); + binaryWriter.Write(s_CachedBytes, 0, length); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/BinaryExtension.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/BinaryExtension.cs.meta new file mode 100644 index 0000000..11cc1b2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/BinaryExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9c8ae7c81e4c674a88100f89ad5812c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultCompressionHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultCompressionHelper.cs new file mode 100644 index 0000000..c5990bb --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultCompressionHelper.cs @@ -0,0 +1,212 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using ICSharpCode.SharpZipLib.GZip; +using System; +using System.IO; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认压缩解压缩辅助器。 + /// + public class DefaultCompressionHelper : Utility.Compression.ICompressionHelper + { + private const int CachedBytesLength = 0x1000; + private readonly byte[] m_CachedBytes = new byte[CachedBytesLength]; + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 要压缩的数据的二进制流的偏移。 + /// 要压缩的数据的二进制流的长度。 + /// 压缩后的数据的二进制流。 + /// 是否压缩数据成功。 + public bool Compress(byte[] bytes, int offset, int length, Stream compressedStream) + { + if (bytes == null) + { + return false; + } + + if (offset < 0 || length < 0 || offset + length > bytes.Length) + { + return false; + } + + if (compressedStream == null) + { + return false; + } + + try + { + GZipOutputStream gZipOutputStream = new GZipOutputStream(compressedStream); + gZipOutputStream.Write(bytes, offset, length); + gZipOutputStream.Finish(); + ProcessHeader(compressedStream); + return true; + } + catch + { + return false; + } + } + + /// + /// 压缩数据。 + /// + /// 要压缩的数据的二进制流。 + /// 压缩后的数据的二进制流。 + /// 是否压缩数据成功。 + public bool Compress(Stream stream, Stream compressedStream) + { + if (stream == null) + { + return false; + } + + if (compressedStream == null) + { + return false; + } + + try + { + GZipOutputStream gZipOutputStream = new GZipOutputStream(compressedStream); + int bytesRead = 0; + while ((bytesRead = stream.Read(m_CachedBytes, 0, CachedBytesLength)) > 0) + { + gZipOutputStream.Write(m_CachedBytes, 0, bytesRead); + } + + gZipOutputStream.Finish(); + ProcessHeader(compressedStream); + return true; + } + catch + { + return false; + } + finally + { + Array.Clear(m_CachedBytes, 0, CachedBytesLength); + } + } + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 要解压缩的数据的二进制流的偏移。 + /// 要解压缩的数据的二进制流的长度。 + /// 解压缩后的数据的二进制流。 + /// 是否解压缩数据成功。 + public bool Decompress(byte[] bytes, int offset, int length, Stream decompressedStream) + { + if (bytes == null) + { + return false; + } + + if (offset < 0 || length < 0 || offset + length > bytes.Length) + { + return false; + } + + if (decompressedStream == null) + { + return false; + } + + MemoryStream memoryStream = null; + try + { + memoryStream = new MemoryStream(bytes, offset, length, false); + using (GZipInputStream gZipInputStream = new GZipInputStream(memoryStream)) + { + int bytesRead = 0; + while ((bytesRead = gZipInputStream.Read(m_CachedBytes, 0, CachedBytesLength)) > 0) + { + decompressedStream.Write(m_CachedBytes, 0, bytesRead); + } + } + + return true; + } + catch + { + return false; + } + finally + { + if (memoryStream != null) + { + memoryStream.Dispose(); + memoryStream = null; + } + + Array.Clear(m_CachedBytes, 0, CachedBytesLength); + } + } + + /// + /// 解压缩数据。 + /// + /// 要解压缩的数据的二进制流。 + /// 解压缩后的数据的二进制流。 + /// 是否解压缩数据成功。 + public bool Decompress(Stream stream, Stream decompressedStream) + { + if (stream == null) + { + return false; + } + + if (decompressedStream == null) + { + return false; + } + + try + { + GZipInputStream gZipInputStream = new GZipInputStream(stream); + int bytesRead = 0; + while ((bytesRead = gZipInputStream.Read(m_CachedBytes, 0, CachedBytesLength)) > 0) + { + decompressedStream.Write(m_CachedBytes, 0, bytesRead); + } + + return true; + } + catch + { + return false; + } + finally + { + Array.Clear(m_CachedBytes, 0, CachedBytesLength); + } + } + + private static void ProcessHeader(Stream compressedStream) + { + if (compressedStream.Length >= 8L) + { + long current = compressedStream.Position; + compressedStream.Position = 4L; + compressedStream.WriteByte(25); + compressedStream.WriteByte(134); + compressedStream.WriteByte(2); + compressedStream.WriteByte(32); + compressedStream.Position = current; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultCompressionHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultCompressionHelper.cs.meta new file mode 100644 index 0000000..193ed8a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultCompressionHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d572c5f6d619fd4cab0970b865300f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultJsonHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultJsonHelper.cs new file mode 100644 index 0000000..daa90cf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultJsonHelper.cs @@ -0,0 +1,56 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认 JSON 函数集辅助器。 + /// + public class DefaultJsonHelper : Utility.Json.IJsonHelper + { + /// + /// 将对象序列化为 JSON 字符串。 + /// + /// 要序列化的对象。 + /// 序列化后的 JSON 字符串。 + public string ToJson(object obj) + { + return JsonUtility.ToJson(obj); + //return JsonMapper.ToJson(obj); + //return JsonConvert.SerializeObject(obj); + } + + /// + /// 将 JSON 字符串反序列化为对象。 + /// + /// 对象类型。 + /// 要反序列化的 JSON 字符串。 + /// 反序列化后的对象。 + public T ToObject(string json) + { + return JsonUtility.FromJson(json); + //return JsonMapper.ToObject(json); + //return JsonConvert.DeserializeObject(json); + } + + /// + /// 将 JSON 字符串反序列化为对象。 + /// + /// 对象类型。 + /// 要反序列化的 JSON 字符串。 + /// 反序列化后的对象。 + public object ToObject(Type objectType, string json) + { + return JsonUtility.FromJson(json, objectType); + //throw new NotSupportedException("ToObject(Type objectType, string json)"); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultJsonHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultJsonHelper.cs.meta new file mode 100644 index 0000000..72bb5e4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultJsonHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7bba1aecb54101942a686f78ca5888b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultLogHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultLogHelper.cs new file mode 100644 index 0000000..c390ba6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultLogHelper.cs @@ -0,0 +1,48 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认游戏框架日志辅助器。 + /// + public class DefaultLogHelper : GameFrameworkLog.ILogHelper + { + /// + /// 记录日志。 + /// + /// 日志等级。 + /// 日志内容。 + public void Log(GameFrameworkLogLevel level, object message) + { + switch (level) + { + case GameFrameworkLogLevel.Debug: + Debug.Log(Utility.Text.Format("{0}", message)); + break; + + case GameFrameworkLogLevel.Info: + Debug.Log(message.ToString()); + break; + + case GameFrameworkLogLevel.Warning: + Debug.LogWarning(message.ToString()); + break; + + case GameFrameworkLogLevel.Error: + Debug.LogError(message.ToString()); + break; + + default: + throw new GameFrameworkException(message.ToString()); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultLogHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultLogHelper.cs.meta new file mode 100644 index 0000000..e102ffe --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultLogHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 646cb891dff23ba49982a2710fd1a218 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultTextHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultTextHelper.cs new file mode 100644 index 0000000..901bd47 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultTextHelper.cs @@ -0,0 +1,592 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; +using System.Text; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认字符辅助器。 + /// + public class DefaultTextHelper : Utility.Text.ITextHelper + { + private const int StringBuilderCapacity = 1024; + + [ThreadStatic] + private static StringBuilder s_CachedStringBuilder = null; + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数的类型。 + /// 字符串格式。 + /// 字符串参数。 + /// 格式化后的字符串。 + public string Format(string format, T arg) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串参数 15 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 字符串参数 15。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return s_CachedStringBuilder.ToString(); + } + + /// + /// 获取格式化字符串。 + /// + /// 字符串参数 1 的类型。 + /// 字符串参数 2 的类型。 + /// 字符串参数 3 的类型。 + /// 字符串参数 4 的类型。 + /// 字符串参数 5 的类型。 + /// 字符串参数 6 的类型。 + /// 字符串参数 7 的类型。 + /// 字符串参数 8 的类型。 + /// 字符串参数 9 的类型。 + /// 字符串参数 10 的类型。 + /// 字符串参数 11 的类型。 + /// 字符串参数 12 的类型。 + /// 字符串参数 13 的类型。 + /// 字符串参数 14 的类型。 + /// 字符串参数 15 的类型。 + /// 字符串参数 16 的类型。 + /// 字符串格式。 + /// 字符串参数 1。 + /// 字符串参数 2。 + /// 字符串参数 3。 + /// 字符串参数 4。 + /// 字符串参数 5。 + /// 字符串参数 6。 + /// 字符串参数 7。 + /// 字符串参数 8。 + /// 字符串参数 9。 + /// 字符串参数 10。 + /// 字符串参数 11。 + /// 字符串参数 12。 + /// 字符串参数 13。 + /// 字符串参数 14。 + /// 字符串参数 15。 + /// 字符串参数 16。 + /// 格式化后的字符串。 + public string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + if (format == null) + { + throw new GameFrameworkException("Format is invalid."); + } + + CheckCachedStringBuilder(); + s_CachedStringBuilder.Length = 0; + s_CachedStringBuilder.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + return s_CachedStringBuilder.ToString(); + } + + private static void CheckCachedStringBuilder() + { + if (s_CachedStringBuilder == null) + { + s_CachedStringBuilder = new StringBuilder(StringBuilderCapacity); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultTextHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultTextHelper.cs.meta new file mode 100644 index 0000000..1621105 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultTextHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 371f2cb893135444b96dec3d77b5ec04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultVersionHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultVersionHelper.cs new file mode 100644 index 0000000..a4d67be --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultVersionHelper.cs @@ -0,0 +1,40 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 默认版本号辅助器。 + /// + public class DefaultVersionHelper : Version.IVersionHelper + { + /// + /// 获取游戏版本号。 + /// + public string GameVersion + { + get + { + return Application.version; + } + } + + /// + /// 获取内部游戏版本号。 + /// + public int InternalGameVersion + { + get + { + return 0; + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultVersionHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultVersionHelper.cs.meta new file mode 100644 index 0000000..1d628be --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/DefaultVersionHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d95b198d6da721458ed6ffc6fc1697c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Helper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Helper.cs new file mode 100644 index 0000000..f91e615 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Helper.cs @@ -0,0 +1,75 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// 辅助器创建器相关的实用函数。 + /// + public static class Helper + { + /// + /// 创建辅助器。 + /// + /// 要创建的辅助器类型。 + /// 要创建的辅助器类型名称。 + /// 若要创建的辅助器类型为空时,使用的自定义辅助器类型。 + /// 创建的辅助器。 + public static T CreateHelper(string helperTypeName, T customHelper) where T : MonoBehaviour + { + return CreateHelper(helperTypeName, customHelper, 0); + } + + /// + /// 创建辅助器。 + /// + /// 要创建的辅助器类型。 + /// 要创建的辅助器类型名称。 + /// 若要创建的辅助器类型为空时,使用的自定义辅助器类型。 + /// 要创建的辅助器索引。 + /// 创建的辅助器。 + public static T CreateHelper(string helperTypeName, T customHelper, int index) where T : MonoBehaviour + { + T helper = null; + if (!string.IsNullOrEmpty(helperTypeName)) + { + System.Type helperType = Utility.Assembly.GetType(helperTypeName); + if (helperType == null) + { + Log.Warning("Can not find helper type '{0}'.", helperTypeName); + return null; + } + + if (!typeof(T).IsAssignableFrom(helperType)) + { + Log.Warning("Type '{0}' is not assignable from '{1}'.", typeof(T).FullName, helperType.FullName); + return null; + } + + helper = (T)new GameObject().AddComponent(helperType); + } + else if (customHelper == null) + { + Log.Warning("You must set custom helper with '{0}' type first.", typeof(T).FullName); + return null; + } + else if (customHelper.gameObject.InScene()) + { + helper = index > 0 ? Object.Instantiate(customHelper) : customHelper; + } + else + { + helper = Object.Instantiate(customHelper); + } + + return helper; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Helper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Helper.cs.meta new file mode 100644 index 0000000..f805aa4 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Helper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7b03d310d08d45429a94d6f62c942b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Log.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Log.cs new file mode 100644 index 0000000..d0a5b36 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Log.cs @@ -0,0 +1,2728 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System.Diagnostics; + +namespace UnityGameFramework.Runtime +{ + /// + /// 日志工具集。 + /// + public static class Log + { + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(object message) + { + GameFrameworkLog.Debug(message); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string message) + { + GameFrameworkLog.Debug(message); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T arg) + { + GameFrameworkLog.Debug(format, arg); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2) + { + GameFrameworkLog.Debug(format, arg1, arg2); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + + /// + /// 打印调试级别日志,用于记录调试类日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + /// 仅在带有 ENABLE_LOG、ENABLE_DEBUG_LOG 或 ENABLE_DEBUG_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_DEBUG_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + public static void Debug(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + GameFrameworkLog.Debug(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(object message) + { + GameFrameworkLog.Info(message); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string message) + { + GameFrameworkLog.Info(message); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T arg) + { + GameFrameworkLog.Info(format, arg); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2) + { + GameFrameworkLog.Info(format, arg1, arg2); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + + /// + /// 打印信息级别日志,用于记录程序正常运行日志信息。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + /// 仅在带有 ENABLE_LOG、ENABLE_INFO_LOG、ENABLE_DEBUG_AND_ABOVE_LOG 或 ENABLE_INFO_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_INFO_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + public static void Info(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + GameFrameworkLog.Info(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(object message) + { + GameFrameworkLog.Warning(message); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string message) + { + GameFrameworkLog.Warning(message); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T arg) + { + GameFrameworkLog.Warning(format, arg); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2) + { + GameFrameworkLog.Warning(format, arg1, arg2); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + + /// + /// 打印警告级别日志,建议在发生局部功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + /// 仅在带有 ENABLE_LOG、ENABLE_WARNING_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG 或 ENABLE_WARNING_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_WARNING_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + public static void Warning(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + GameFrameworkLog.Warning(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(object message) + { + GameFrameworkLog.Error(message); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string message) + { + GameFrameworkLog.Error(message); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T arg) + { + GameFrameworkLog.Error(format, arg); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2) + { + GameFrameworkLog.Error(format, arg1, arg2); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + + /// + /// 打印错误级别日志,建议在发生功能逻辑错误,但尚不会导致游戏崩溃或异常时使用。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + /// 仅在带有 ENABLE_LOG、ENABLE_ERROR_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG 或 ENABLE_ERROR_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_ERROR_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + public static void Error(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + GameFrameworkLog.Error(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(object message) + { + GameFrameworkLog.Fatal(message); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志内容。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string message) + { + GameFrameworkLog.Fatal(message); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数的类型。 + /// 日志格式。 + /// 日志参数。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T arg) + { + GameFrameworkLog.Fatal(format, arg); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2) + { + GameFrameworkLog.Fatal(format, arg1, arg2); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + + /// + /// 打印严重错误级别日志,建议在发生严重错误,可能导致游戏崩溃或异常时使用,此时应尝试重启进程或重建游戏框架。 + /// + /// 日志参数 1 的类型。 + /// 日志参数 2 的类型。 + /// 日志参数 3 的类型。 + /// 日志参数 4 的类型。 + /// 日志参数 5 的类型。 + /// 日志参数 6 的类型。 + /// 日志参数 7 的类型。 + /// 日志参数 8 的类型。 + /// 日志参数 9 的类型。 + /// 日志参数 10 的类型。 + /// 日志参数 11 的类型。 + /// 日志参数 12 的类型。 + /// 日志参数 13 的类型。 + /// 日志参数 14 的类型。 + /// 日志参数 15 的类型。 + /// 日志参数 16 的类型。 + /// 日志格式。 + /// 日志参数 1。 + /// 日志参数 2。 + /// 日志参数 3。 + /// 日志参数 4。 + /// 日志参数 5。 + /// 日志参数 6。 + /// 日志参数 7。 + /// 日志参数 8。 + /// 日志参数 9。 + /// 日志参数 10。 + /// 日志参数 11。 + /// 日志参数 12。 + /// 日志参数 13。 + /// 日志参数 14。 + /// 日志参数 15。 + /// 日志参数 16。 + /// 仅在带有 ENABLE_LOG、ENABLE_FATAL_LOG、ENABLE_DEBUG_AND_ABOVE_LOG、ENABLE_INFO_AND_ABOVE_LOG、ENABLE_WARNING_AND_ABOVE_LOG、ENABLE_ERROR_AND_ABOVE_LOG 或 ENABLE_FATAL_AND_ABOVE_LOG 预编译选项时生效。 + [Conditional("ENABLE_LOG")] + [Conditional("ENABLE_FATAL_LOG")] + [Conditional("ENABLE_DEBUG_AND_ABOVE_LOG")] + [Conditional("ENABLE_INFO_AND_ABOVE_LOG")] + [Conditional("ENABLE_WARNING_AND_ABOVE_LOG")] + [Conditional("ENABLE_ERROR_AND_ABOVE_LOG")] + [Conditional("ENABLE_FATAL_AND_ABOVE_LOG")] + public static void Fatal(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + GameFrameworkLog.Fatal(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Log.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Log.cs.meta new file mode 100644 index 0000000..136d75d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/Log.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dea5e7b095c6d3b4ea334c381fcd16fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/StringExtension.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/StringExtension.cs new file mode 100644 index 0000000..bcb3ea8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/StringExtension.cs @@ -0,0 +1,66 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +/// +/// 对 string 的扩展方法。 +/// +public static class StringExtension +{ + /// + /// 从指定字符串中的指定位置处开始读取一行。 + /// + /// 指定的字符串。 + /// 从指定位置处开始读取一行,读取后将返回下一行开始的位置。 + /// 读取的一行字符串。 + public static string ReadLine(this string rawString, ref int position) + { + if (position < 0) + { + return null; + } + + int length = rawString.Length; + int offset = position; + while (offset < length) + { + char ch = rawString[offset]; + switch (ch) + { + case '\r': + case '\n': + if (offset > position) + { + string line = rawString.Substring(position, offset - position); + position = offset + 1; + if ((ch == '\r') && (position < length) && (rawString[position] == '\n')) + { + position++; + } + + return line; + } + + offset++; + position++; + break; + + default: + offset++; + break; + } + } + + if (offset > position) + { + string line = rawString.Substring(position, offset - position); + position = offset; + return line; + } + + return null; + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/StringExtension.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/StringExtension.cs.meta new file mode 100644 index 0000000..7bcb29f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/StringExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 809e5c16ec9bc7440ab85cb3626d9263 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/UnityExtension.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/UnityExtension.cs new file mode 100644 index 0000000..e71f51a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/UnityExtension.cs @@ -0,0 +1,347 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using UnityEngine; + +/// +/// 对 Unity 的扩展方法。 +/// +public static class UnityExtension +{ + private static readonly List s_CachedTransforms = new List(); + + /// + /// 获取或增加组件。 + /// + /// 要获取或增加的组件。 + /// 目标对象。 + /// 获取或增加的组件。 + public static T GetOrAddComponent(this GameObject gameObject) where T : Component + { + T component = gameObject.GetComponent(); + if (component == null) + { + component = gameObject.AddComponent(); + } + + return component; + } + + /// + /// 获取或增加组件。 + /// + /// 目标对象。 + /// 要获取或增加的组件类型。 + /// 获取或增加的组件。 + public static Component GetOrAddComponent(this GameObject gameObject, Type type) + { + Component component = gameObject.GetComponent(type); + if (component == null) + { + component = gameObject.AddComponent(type); + } + + return component; + } + + /// + /// 获取 GameObject 是否在场景中。 + /// + /// 目标对象。 + /// GameObject 是否在场景中。 + /// 若返回 true,表明此 GameObject 是一个场景中的实例对象;若返回 false,表明此 GameObject 是一个 Prefab。 + public static bool InScene(this GameObject gameObject) + { + return gameObject.scene.name != null; + } + + /// + /// 递归设置游戏对象的层次。 + /// + /// 对象。 + /// 目标层次的编号。 + public static void SetLayerRecursively(this GameObject gameObject, int layer) + { + gameObject.GetComponentsInChildren(true, s_CachedTransforms); + for (int i = 0; i < s_CachedTransforms.Count; i++) + { + s_CachedTransforms[i].gameObject.layer = layer; + } + + s_CachedTransforms.Clear(); + } + + /// + /// 取 的 (x, y, z) 转换为 的 (x, z)。 + /// + /// 要转换的 Vector3。 + /// 转换后的 Vector2。 + public static Vector2 ToVector2(this Vector3 vector3) + { + return new Vector2(vector3.x, vector3.z); + } + + /// + /// 取 的 (x, y) 转换为 的 (x, 0, y)。 + /// + /// 要转换的 Vector2。 + /// 转换后的 Vector3。 + public static Vector3 ToVector3(this Vector2 vector2) + { + return new Vector3(vector2.x, 0f, vector2.y); + } + + /// + /// 取 的 (x, y) 和给定参数 y 转换为 的 (x, 参数 y, y)。 + /// + /// 要转换的 Vector2。 + /// Vector3 的 y 值。 + /// 转换后的 Vector3。 + public static Vector3 ToVector3(this Vector2 vector2, float y) + { + return new Vector3(vector2.x, y, vector2.y); + } + + #region Transform + + /// + /// 设置绝对位置的 x 坐标。 + /// + /// 对象。 + /// x 坐标值。 + public static void SetPositionX(this Transform transform, float newValue) + { + Vector3 v = transform.position; + v.x = newValue; + transform.position = v; + } + + /// + /// 设置绝对位置的 y 坐标。 + /// + /// 对象。 + /// y 坐标值。 + public static void SetPositionY(this Transform transform, float newValue) + { + Vector3 v = transform.position; + v.y = newValue; + transform.position = v; + } + + /// + /// 设置绝对位置的 z 坐标。 + /// + /// 对象。 + /// z 坐标值。 + public static void SetPositionZ(this Transform transform, float newValue) + { + Vector3 v = transform.position; + v.z = newValue; + transform.position = v; + } + + /// + /// 增加绝对位置的 x 坐标。 + /// + /// 对象。 + /// x 坐标值增量。 + public static void AddPositionX(this Transform transform, float deltaValue) + { + Vector3 v = transform.position; + v.x += deltaValue; + transform.position = v; + } + + /// + /// 增加绝对位置的 y 坐标。 + /// + /// 对象。 + /// y 坐标值增量。 + public static void AddPositionY(this Transform transform, float deltaValue) + { + Vector3 v = transform.position; + v.y += deltaValue; + transform.position = v; + } + + /// + /// 增加绝对位置的 z 坐标。 + /// + /// 对象。 + /// z 坐标值增量。 + public static void AddPositionZ(this Transform transform, float deltaValue) + { + Vector3 v = transform.position; + v.z += deltaValue; + transform.position = v; + } + + /// + /// 设置相对位置的 x 坐标。 + /// + /// 对象。 + /// x 坐标值。 + public static void SetLocalPositionX(this Transform transform, float newValue) + { + Vector3 v = transform.localPosition; + v.x = newValue; + transform.localPosition = v; + } + + /// + /// 设置相对位置的 y 坐标。 + /// + /// 对象。 + /// y 坐标值。 + public static void SetLocalPositionY(this Transform transform, float newValue) + { + Vector3 v = transform.localPosition; + v.y = newValue; + transform.localPosition = v; + } + + /// + /// 设置相对位置的 z 坐标。 + /// + /// 对象。 + /// z 坐标值。 + public static void SetLocalPositionZ(this Transform transform, float newValue) + { + Vector3 v = transform.localPosition; + v.z = newValue; + transform.localPosition = v; + } + + /// + /// 增加相对位置的 x 坐标。 + /// + /// 对象。 + /// x 坐标值。 + public static void AddLocalPositionX(this Transform transform, float deltaValue) + { + Vector3 v = transform.localPosition; + v.x += deltaValue; + transform.localPosition = v; + } + + /// + /// 增加相对位置的 y 坐标。 + /// + /// 对象。 + /// y 坐标值。 + public static void AddLocalPositionY(this Transform transform, float deltaValue) + { + Vector3 v = transform.localPosition; + v.y += deltaValue; + transform.localPosition = v; + } + + /// + /// 增加相对位置的 z 坐标。 + /// + /// 对象。 + /// z 坐标值。 + public static void AddLocalPositionZ(this Transform transform, float deltaValue) + { + Vector3 v = transform.localPosition; + v.z += deltaValue; + transform.localPosition = v; + } + + /// + /// 设置相对尺寸的 x 分量。 + /// + /// 对象。 + /// x 分量值。 + public static void SetLocalScaleX(this Transform transform, float newValue) + { + Vector3 v = transform.localScale; + v.x = newValue; + transform.localScale = v; + } + + /// + /// 设置相对尺寸的 y 分量。 + /// + /// 对象。 + /// y 分量值。 + public static void SetLocalScaleY(this Transform transform, float newValue) + { + Vector3 v = transform.localScale; + v.y = newValue; + transform.localScale = v; + } + + /// + /// 设置相对尺寸的 z 分量。 + /// + /// 对象。 + /// z 分量值。 + public static void SetLocalScaleZ(this Transform transform, float newValue) + { + Vector3 v = transform.localScale; + v.z = newValue; + transform.localScale = v; + } + + /// + /// 增加相对尺寸的 x 分量。 + /// + /// 对象。 + /// x 分量增量。 + public static void AddLocalScaleX(this Transform transform, float deltaValue) + { + Vector3 v = transform.localScale; + v.x += deltaValue; + transform.localScale = v; + } + + /// + /// 增加相对尺寸的 y 分量。 + /// + /// 对象。 + /// y 分量增量。 + public static void AddLocalScaleY(this Transform transform, float deltaValue) + { + Vector3 v = transform.localScale; + v.y += deltaValue; + transform.localScale = v; + } + + /// + /// 增加相对尺寸的 z 分量。 + /// + /// 对象。 + /// z 分量增量。 + public static void AddLocalScaleZ(this Transform transform, float deltaValue) + { + Vector3 v = transform.localScale; + v.z += deltaValue; + transform.localScale = v; + } + + /// + /// 二维空间下使 指向指向目标点的算法,使用世界坐标。 + /// + /// 对象。 + /// 要朝向的二维坐标点。 + /// 假定其 forward 向量为 + public static void LookAt2D(this Transform transform, Vector2 lookAtPoint2D) + { + Vector3 vector = lookAtPoint2D.ToVector3() - transform.position; + vector.y = 0f; + + if (vector.magnitude > 0f) + { + transform.rotation = Quaternion.LookRotation(vector.normalized, Vector3.up); + } + } + + #endregion Transform +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/UnityExtension.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/UnityExtension.cs.meta new file mode 100644 index 0000000..7738c7d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Utility/UnityExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24f918603ece9974690d60aa69d97be2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable.meta new file mode 100644 index 0000000..e345c4f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8f71cb3d04c9a3342b05140a90a66e9f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarBoolean.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarBoolean.cs new file mode 100644 index 0000000..1def04d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarBoolean.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Boolean 变量类。 + /// + public sealed class VarBoolean : Variable + { + /// + /// 初始化 System.Boolean 变量类的新实例。 + /// + public VarBoolean() + { + } + + /// + /// 从 System.Boolean 到 System.Boolean 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarBoolean(bool value) + { + VarBoolean varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Boolean 变量类到 System.Boolean 的隐式转换。 + /// + /// 值。 + public static implicit operator bool(VarBoolean value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarBoolean.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarBoolean.cs.meta new file mode 100644 index 0000000..10ec55f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarBoolean.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 951d24bf51d09c64e8cd2ac824a363b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByte.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByte.cs new file mode 100644 index 0000000..d238bc7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByte.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Byte 变量类。 + /// + public sealed class VarByte : Variable + { + /// + /// 初始化 System.Byte 变量类的新实例。 + /// + public VarByte() + { + } + + /// + /// 从 System.Byte 到 System.Byte 变量类的隐式转换。 + /// + /// 值。 + /// implicit operator 隐式转换关键字 + public static implicit operator VarByte(byte value) + { + VarByte varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Byte 变量类到 System.Byte 的隐式转换。 + /// + /// 值。 + public static implicit operator byte(VarByte value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByte.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByte.cs.meta new file mode 100644 index 0000000..631cca8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByte.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 028b1842c42f7bf4999e1aaffed3b451 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByteArray.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByteArray.cs new file mode 100644 index 0000000..17edeaf --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByteArray.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Byte 数组变量类。 + /// + public sealed class VarByteArray : Variable + { + /// + /// 初始化 System.Byte 数组变量类的新实例。 + /// + public VarByteArray() + { + } + + /// + /// 从 System.Byte 数组到 System.Byte 数组变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarByteArray(byte[] value) + { + VarByteArray varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Byte 数组变量类到 System.Byte 数组的隐式转换。 + /// + /// 值。 + public static implicit operator byte[](VarByteArray value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByteArray.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByteArray.cs.meta new file mode 100644 index 0000000..e2ccc9f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarByteArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbb9b35f2ec6f8f4bb8bb6c361eb8ef6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarChar.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarChar.cs new file mode 100644 index 0000000..0a38411 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarChar.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Char 变量类。 + /// + public sealed class VarChar : Variable + { + /// + /// 初始化 System.Char 变量类的新实例。 + /// + public VarChar() + { + } + + /// + /// 从 System.Char 到 System.Char 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarChar(char value) + { + VarChar varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Char 变量类到 System.Char 的隐式转换。 + /// + /// 值。 + public static implicit operator char(VarChar value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarChar.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarChar.cs.meta new file mode 100644 index 0000000..3b78eb9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarChar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17c91d9b1ebba834385874fcf8c1076a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarCharArray.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarCharArray.cs new file mode 100644 index 0000000..30763cc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarCharArray.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Char 数组变量类。 + /// + public sealed class VarCharArray : Variable + { + /// + /// 初始化 System.Char 数组变量类的新实例。 + /// + public VarCharArray() + { + } + + /// + /// 从 System.Char 数组到 System.Char 数组变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarCharArray(char[] value) + { + VarCharArray varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Char 数组变量类到 System.Char 数组的隐式转换。 + /// + /// 值。 + public static implicit operator char[](VarCharArray value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarCharArray.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarCharArray.cs.meta new file mode 100644 index 0000000..64422cc --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarCharArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 74c192285e6e9d8469961735fd7bc29e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor.cs new file mode 100644 index 0000000..61432c3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Color 变量类。 + /// + public sealed class VarColor : Variable + { + /// + /// 初始化 UnityEngine.Color 变量类的新实例。 + /// + public VarColor() + { + } + + /// + /// 从 UnityEngine.Color 到 UnityEngine.Color 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarColor(Color value) + { + VarColor varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Color 变量类到 UnityEngine.Color 的隐式转换。 + /// + /// 值。 + public static implicit operator Color(VarColor value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor.cs.meta new file mode 100644 index 0000000..f6b2dbe --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7b2e4000c824c341bd90a5886dd0893 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor32.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor32.cs new file mode 100644 index 0000000..02ec02b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor32.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Color32 变量类。 + /// + public sealed class VarColor32 : Variable + { + /// + /// 初始化 UnityEngine.Color32 变量类的新实例。 + /// + public VarColor32() + { + } + + /// + /// 从 UnityEngine.Color32 到 UnityEngine.Color32 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarColor32(Color32 value) + { + VarColor32 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Color32 变量类到 UnityEngine.Color32 的隐式转换。 + /// + /// 值。 + public static implicit operator Color32(VarColor32 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor32.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor32.cs.meta new file mode 100644 index 0000000..c5c4af6 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarColor32.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f31aea41afccdc843a7cc7de09a7fc9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDateTime.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDateTime.cs new file mode 100644 index 0000000..7d83c79 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDateTime.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using System; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.DateTime 变量类。 + /// + public sealed class VarDateTime : Variable + { + /// + /// 初始化 System.DateTime 变量类的新实例。 + /// + public VarDateTime() + { + } + + /// + /// 从 System.DateTime 到 System.DateTime 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarDateTime(DateTime value) + { + VarDateTime varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.DateTime 变量类到 System.DateTime 的隐式转换。 + /// + /// 值。 + public static implicit operator DateTime(VarDateTime value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDateTime.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDateTime.cs.meta new file mode 100644 index 0000000..7b03c2c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDateTime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b58529251d8325439e3988047d2f019 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDecimal.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDecimal.cs new file mode 100644 index 0000000..43257e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDecimal.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Decimal 变量类。 + /// + public sealed class VarDecimal : Variable + { + /// + /// 初始化 System.Decimal 变量类的新实例。 + /// + public VarDecimal() + { + } + + /// + /// 从 System.Decimal 到 System.Decimal 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarDecimal(decimal value) + { + VarDecimal varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Decimal 变量类到 System.Decimal 的隐式转换。 + /// + /// 值。 + public static implicit operator decimal(VarDecimal value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDecimal.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDecimal.cs.meta new file mode 100644 index 0000000..ac5b497 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDecimal.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8bd5d553ed3aea4485bf78964f09708 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDouble.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDouble.cs new file mode 100644 index 0000000..9b6da5e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDouble.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Double 变量类。 + /// + public sealed class VarDouble : Variable + { + /// + /// 初始化 System.Double 变量类的新实例。 + /// + public VarDouble() + { + } + + /// + /// 从 System.Double 到 System.Double 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarDouble(double value) + { + VarDouble varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Double 变量类到 System.Double 的隐式转换。 + /// + /// 值。 + public static implicit operator double(VarDouble value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDouble.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDouble.cs.meta new file mode 100644 index 0000000..98661ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarDouble.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55b52e85a025f734495ed0e888633468 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarGameObject.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarGameObject.cs new file mode 100644 index 0000000..c0cc5c2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarGameObject.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.GameObject 变量类。 + /// + public sealed class VarGameObject : Variable + { + /// + /// 初始化 UnityEngine.GameObject 变量类的新实例。 + /// + public VarGameObject() + { + } + + /// + /// 从 UnityEngine.GameObject 到 UnityEngine.GameObject 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarGameObject(GameObject value) + { + VarGameObject varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.GameObject 变量类到 UnityEngine.GameObject 的隐式转换。 + /// + /// 值。 + public static implicit operator GameObject(VarGameObject value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarGameObject.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarGameObject.cs.meta new file mode 100644 index 0000000..7fda629 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarGameObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c339e4000da5e645993ae5bb3c79554 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt16.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt16.cs new file mode 100644 index 0000000..055656b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt16.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Int16 变量类。 + /// + public sealed class VarInt16 : Variable + { + /// + /// 初始化 System.Int16 变量类的新实例。 + /// + public VarInt16() + { + } + + /// + /// 从 System.Int16 到 System.Int16 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarInt16(short value) + { + VarInt16 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Int16 变量类到 System.Int16 的隐式转换。 + /// + /// 值。 + public static implicit operator short(VarInt16 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt16.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt16.cs.meta new file mode 100644 index 0000000..4a27d15 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt16.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb22474f50a73704ebdc00b32ba1fd93 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt32.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt32.cs new file mode 100644 index 0000000..1a04cf9 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt32.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Int32 变量类。 + /// + public sealed class VarInt32 : Variable + { + /// + /// 初始化 System.Int32 变量类的新实例。 + /// + public VarInt32() + { + } + + /// + /// 从 System.Int32 到 System.Int32 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarInt32(int value) + { + VarInt32 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Int32 变量类到 System.Int32 的隐式转换。 + /// + /// 值。 + public static implicit operator int(VarInt32 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt32.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt32.cs.meta new file mode 100644 index 0000000..8f4d62d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt32.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f82188cc963752848a236f4fed834740 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt64.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt64.cs new file mode 100644 index 0000000..9cdc090 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt64.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Int64 变量类。 + /// + public sealed class VarInt64 : Variable + { + /// + /// 初始化 System.Int64 变量类的新实例。 + /// + public VarInt64() + { + } + + /// + /// 从 System.Int64 到 System.Int64 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarInt64(long value) + { + VarInt64 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Int64 变量类到 System.Int64 的隐式转换。 + /// + /// 值。 + public static implicit operator long(VarInt64 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt64.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt64.cs.meta new file mode 100644 index 0000000..a52a798 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarInt64.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 13f2695725ed09648a9fc2b506584a0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarMaterial.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarMaterial.cs new file mode 100644 index 0000000..09f73f3 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarMaterial.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Material 变量类。 + /// + public sealed class VarMaterial : Variable + { + /// + /// 初始化 UnityEngine.Material 变量类的新实例。 + /// + public VarMaterial() + { + } + + /// + /// 从 UnityEngine.Material 到 UnityEngine.Material 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarMaterial(Material value) + { + VarMaterial varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Material 变量类到 UnityEngine.Material 的隐式转换。 + /// + /// 值。 + public static implicit operator Material(VarMaterial value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarMaterial.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarMaterial.cs.meta new file mode 100644 index 0000000..6b6a0e2 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarMaterial.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45b6448300498c842a0facd7b2b6d45c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarObject.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarObject.cs new file mode 100644 index 0000000..1d6f175 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarObject.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Object 变量类。 + /// + public sealed class VarObject : Variable + { + /// + /// 初始化 System.Object 变量类的新实例。 + /// + public VarObject() + { + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarObject.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarObject.cs.meta new file mode 100644 index 0000000..dae3a94 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3b2d458c0eb0244c905a819c9fec4f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarQuaternion.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarQuaternion.cs new file mode 100644 index 0000000..077ec3f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarQuaternion.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Quaternion 变量类。 + /// + public sealed class VarQuaternion : Variable + { + /// + /// 初始化 UnityEngine.Quaternion 变量类的新实例。 + /// + public VarQuaternion() + { + } + + /// + /// 从 UnityEngine.Quaternion 到 UnityEngine.Quaternion 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarQuaternion(Quaternion value) + { + VarQuaternion varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Quaternion 变量类到 UnityEngine.Quaternion 的隐式转换。 + /// + /// 值。 + public static implicit operator Quaternion(VarQuaternion value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarQuaternion.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarQuaternion.cs.meta new file mode 100644 index 0000000..213ce68 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarQuaternion.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 411c1800741f3594d80ef8ce06797ca4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarRect.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarRect.cs new file mode 100644 index 0000000..f328111 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarRect.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Rect 变量类。 + /// + public sealed class VarRect : Variable + { + /// + /// 初始化 UnityEngine.Rect 变量类的新实例。 + /// + public VarRect() + { + } + + /// + /// 从 UnityEngine.Rect 到 UnityEngine.Rect 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarRect(Rect value) + { + VarRect varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Rect 变量类到 UnityEngine.Rect 的隐式转换。 + /// + /// 值。 + public static implicit operator Rect(VarRect value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarRect.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarRect.cs.meta new file mode 100644 index 0000000..8167184 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarRect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee11011c267861947bfbd3353b91bd12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSByte.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSByte.cs new file mode 100644 index 0000000..cabd656 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSByte.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.SByte 变量类。 + /// + public sealed class VarSByte : Variable + { + /// + /// 初始化 System.SByte 变量类的新实例。 + /// + public VarSByte() + { + } + + /// + /// 从 System.SByte 到 System.SByte 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarSByte(sbyte value) + { + VarSByte varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.SByte 变量类到 System.SByte 的隐式转换。 + /// + /// 值。 + public static implicit operator sbyte(VarSByte value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSByte.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSByte.cs.meta new file mode 100644 index 0000000..d4a8514 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSByte.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e0877a15fd8ef34699d6e817a9c04bd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSingle.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSingle.cs new file mode 100644 index 0000000..520d6a8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSingle.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.Single 变量类。 + /// + public sealed class VarSingle : Variable + { + /// + /// 初始化 System.Single 变量类的新实例。 + /// + public VarSingle() + { + } + + /// + /// 从 System.Single 到 System.Single 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarSingle(float value) + { + VarSingle varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.Single 变量类到 System.Single 的隐式转换。 + /// + /// 值。 + public static implicit operator float(VarSingle value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSingle.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSingle.cs.meta new file mode 100644 index 0000000..f53d09e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarSingle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a31b440f69e7f04f9afabe202d14550 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarString.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarString.cs new file mode 100644 index 0000000..c44016e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarString.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.String 变量类。 + /// + public sealed class VarString : Variable + { + /// + /// 初始化 System.String 变量类的新实例。 + /// + public VarString() + { + } + + /// + /// 从 System.String 到 System.String 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarString(string value) + { + VarString varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.String 变量类到 System.String 的隐式转换。 + /// + /// 值。 + public static implicit operator string(VarString value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarString.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarString.cs.meta new file mode 100644 index 0000000..a602417 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d45679f4a06fe6244ad4ff88dca368a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTexture.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTexture.cs new file mode 100644 index 0000000..acd4df5 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTexture.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Texture 变量类。 + /// + public sealed class VarTexture : Variable + { + /// + /// 初始化 UnityEngine.Texture 变量类的新实例。 + /// + public VarTexture() + { + } + + /// + /// 从 UnityEngine.Texture 到 UnityEngine.Texture 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarTexture(Texture value) + { + VarTexture varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Texture 变量类到 UnityEngine.Texture 的隐式转换。 + /// + /// 值。 + public static implicit operator Texture(VarTexture value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTexture.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTexture.cs.meta new file mode 100644 index 0000000..4f72c27 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTexture.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0f43d324b63e5d48933b078ca2cc5f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTransform.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTransform.cs new file mode 100644 index 0000000..f017173 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTransform.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Transform 变量类。 + /// + public sealed class VarTransform : Variable + { + /// + /// 初始化 UnityEngine.Transform 变量类的新实例。 + /// + public VarTransform() + { + } + + /// + /// 从 UnityEngine.Transform 到 UnityEngine.Transform 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarTransform(Transform value) + { + VarTransform varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Transform 变量类到 UnityEngine.Transform 的隐式转换。 + /// + /// 值。 + public static implicit operator Transform(VarTransform value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTransform.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTransform.cs.meta new file mode 100644 index 0000000..51d1324 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarTransform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dff6037db6354304d82d9aaf079d5c63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt16.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt16.cs new file mode 100644 index 0000000..09a2dd7 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt16.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.UInt16 变量类。 + /// + public sealed class VarUInt16 : Variable + { + /// + /// 初始化 System.UInt16 变量类的新实例。 + /// + public VarUInt16() + { + } + + /// + /// 从 System.UInt16 到 System.UInt16 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarUInt16(ushort value) + { + VarUInt16 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.UInt16 变量类到 System.UInt16 的隐式转换。 + /// + /// 值。 + public static implicit operator ushort(VarUInt16 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt16.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt16.cs.meta new file mode 100644 index 0000000..6303851 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt16.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c158720cba058174995252c289e561b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt32.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt32.cs new file mode 100644 index 0000000..e95cdf0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt32.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.UInt32 变量类。 + /// + public sealed class VarUInt32 : Variable + { + /// + /// 初始化 System.UInt32 变量类的新实例。 + /// + public VarUInt32() + { + } + + /// + /// 从 System.UInt32 到 System.UInt32 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarUInt32(uint value) + { + VarUInt32 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.UInt32 变量类到 System.UInt32 的隐式转换。 + /// + /// 值。 + public static implicit operator uint(VarUInt32 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt32.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt32.cs.meta new file mode 100644 index 0000000..2a2b4e1 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt32.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec67b25d499a2d34fa1c450a9d165ab0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt64.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt64.cs new file mode 100644 index 0000000..f140563 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt64.cs @@ -0,0 +1,44 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; + +namespace UnityGameFramework.Runtime +{ + /// + /// System.UInt64 变量类。 + /// + public sealed class VarUInt64 : Variable + { + /// + /// 初始化 System.UInt64 变量类的新实例。 + /// + public VarUInt64() + { + } + + /// + /// 从 System.UInt64 到 System.UInt64 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarUInt64(ulong value) + { + VarUInt64 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 System.UInt64 变量类到 System.UInt64 的隐式转换。 + /// + /// 值。 + public static implicit operator ulong(VarUInt64 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt64.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt64.cs.meta new file mode 100644 index 0000000..78ae7a0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUInt64.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0195ac43c505b248a7d9d41beff1436 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUnityObject.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUnityObject.cs new file mode 100644 index 0000000..8caa56e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUnityObject.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Object 变量类。 + /// + public sealed class VarUnityObject : Variable + { + /// + /// 初始化 UnityEngine.Object 变量类的新实例。 + /// + public VarUnityObject() + { + } + + /// + /// 从 UnityEngine.Object 到 UnityEngine.Object 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarUnityObject(Object value) + { + VarUnityObject varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Object 变量类到 UnityEngine.Object 的隐式转换。 + /// + /// 值。 + public static implicit operator Object(VarUnityObject value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUnityObject.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUnityObject.cs.meta new file mode 100644 index 0000000..b0adfea --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarUnityObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc9d733f793fc00468089f8cdd6c1835 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector2.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector2.cs new file mode 100644 index 0000000..09280ee --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector2.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Vector2 变量类。 + /// + public sealed class VarVector2 : Variable + { + /// + /// 初始化 UnityEngine.Vector2 变量类的新实例。 + /// + public VarVector2() + { + } + + /// + /// 从 UnityEngine.Vector2 到 UnityEngine.Vector2 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarVector2(Vector2 value) + { + VarVector2 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Vector2 变量类到 UnityEngine.Vector2 的隐式转换。 + /// + /// 值。 + public static implicit operator Vector2(VarVector2 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector2.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector2.cs.meta new file mode 100644 index 0000000..78ad39a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef03a8d73e6be4348802fc28c4777c49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector3.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector3.cs new file mode 100644 index 0000000..e6d381a --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector3.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Vector3 变量类。 + /// + public sealed class VarVector3 : Variable + { + /// + /// 初始化 UnityEngine.Vector3 变量类的新实例。 + /// + public VarVector3() + { + } + + /// + /// 从 UnityEngine.Vector3 到 UnityEngine.Vector3 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarVector3(Vector3 value) + { + VarVector3 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Vector3 变量类到 UnityEngine.Vector3 的隐式转换。 + /// + /// 值。 + public static implicit operator Vector3(VarVector3 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector3.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector3.cs.meta new file mode 100644 index 0000000..0fd91e0 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector3.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b041a74c058fe54418735010bcfd2a21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector4.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector4.cs new file mode 100644 index 0000000..476526b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector4.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// UnityEngine.Vector4 变量类。 + /// + public sealed class VarVector4 : Variable + { + /// + /// 初始化 UnityEngine.Vector4 变量类的新实例。 + /// + public VarVector4() + { + } + + /// + /// 从 UnityEngine.Vector4 到 UnityEngine.Vector4 变量类的隐式转换。 + /// + /// 值。 + public static implicit operator VarVector4(Vector4 value) + { + VarVector4 varValue = ReferencePool.Acquire(); + varValue.Value = value; + return varValue; + } + + /// + /// 从 UnityEngine.Vector4 变量类到 UnityEngine.Vector4 的隐式转换。 + /// + /// 值。 + public static implicit operator Vector4(VarVector4 value) + { + return value.Value; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector4.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector4.cs.meta new file mode 100644 index 0000000..f6d7301 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/Variable/VarVector4.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30950f09797d4354e883c8c4d2caa7b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest.meta new file mode 100644 index 0000000..cf8106c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 66fef66090127fe46a41b9c2b8f79880 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/UnityWebRequestAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/UnityWebRequestAgentHelper.cs new file mode 100644 index 0000000..542fa48 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/UnityWebRequestAgentHelper.cs @@ -0,0 +1,186 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.WebRequest; +using System; +#if UNITY_5_4_OR_NEWER +using UnityEngine.Networking; +#else +using UnityEngine.Experimental.Networking; +#endif +using Utility = GameFramework.Utility; + +namespace UnityGameFramework.Runtime +{ + /// + /// 使用 UnityWebRequest 实现的 Web 请求代理辅助器。 + /// + public class UnityWebRequestAgentHelper : WebRequestAgentHelperBase, IDisposable + { + private UnityWebRequest m_UnityWebRequest = null; + private bool m_Disposed = false; + + private EventHandler m_WebRequestAgentHelperCompleteEventHandler = null; + private EventHandler m_WebRequestAgentHelperErrorEventHandler = null; + + /// + /// Web 请求代理辅助器完成事件。 + /// + public override event EventHandler WebRequestAgentHelperComplete + { + add + { + m_WebRequestAgentHelperCompleteEventHandler += value; + } + remove + { + m_WebRequestAgentHelperCompleteEventHandler -= value; + } + } + + /// + /// Web 请求代理辅助器错误事件。 + /// + public override event EventHandler WebRequestAgentHelperError + { + add + { + m_WebRequestAgentHelperErrorEventHandler += value; + } + remove + { + m_WebRequestAgentHelperErrorEventHandler -= value; + } + } + + /// + /// 通过 Web 请求代理辅助器发送请求。 + /// + /// 要发送的远程地址。 + /// 用户自定义数据。 + public override void Request(string webRequestUri, object userData) + { + if (m_WebRequestAgentHelperCompleteEventHandler == null || m_WebRequestAgentHelperErrorEventHandler == null) + { + Log.Fatal("Web request agent helper handler is invalid."); + return; + } + + WWWFormInfo wwwFormInfo = (WWWFormInfo)userData; + if (wwwFormInfo.WWWForm == null) + { + m_UnityWebRequest = UnityWebRequest.Get(webRequestUri); + } + else + { + m_UnityWebRequest = UnityWebRequest.Post(webRequestUri, wwwFormInfo.WWWForm); + } + +#if UNITY_2017_2_OR_NEWER + m_UnityWebRequest.SendWebRequest(); +#else + m_UnityWebRequest.Send(); +#endif + } + + /// + /// 通过 Web 请求代理辅助器发送请求。 + /// + /// 要发送的远程地址。 + /// 要发送的数据流。 + /// 用户自定义数据。 + public override void Request(string webRequestUri, byte[] postData, object userData) + { + if (m_WebRequestAgentHelperCompleteEventHandler == null || m_WebRequestAgentHelperErrorEventHandler == null) + { + Log.Fatal("Web request agent helper handler is invalid."); + return; + } + + m_UnityWebRequest = UnityWebRequest.PostWwwForm(webRequestUri, Utility.Converter.GetString(postData)); +#if UNITY_2017_2_OR_NEWER + m_UnityWebRequest.SendWebRequest(); +#else + m_UnityWebRequest.Send(); +#endif + } + + /// + /// 重置 Web 请求代理辅助器。 + /// + public override void Reset() + { + if (m_UnityWebRequest != null) + { + m_UnityWebRequest.Dispose(); + m_UnityWebRequest = null; + } + } + + /// + /// 释放资源。 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 释放资源。 + /// + /// 释放资源标记。 + protected virtual void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_UnityWebRequest != null) + { + m_UnityWebRequest.Dispose(); + m_UnityWebRequest = null; + } + } + + m_Disposed = true; + } + + private void Update() + { + if (m_UnityWebRequest == null || !m_UnityWebRequest.isDone) + { + return; + } + + bool isError = false; +#if UNITY_2020_2_OR_NEWER + isError = m_UnityWebRequest.result != UnityWebRequest.Result.Success; +#elif UNITY_2017_1_OR_NEWER + isError = m_UnityWebRequest.isNetworkError || m_UnityWebRequest.isHttpError; +#else + isError = m_UnityWebRequest.isError; +#endif + if (isError) + { + WebRequestAgentHelperErrorEventArgs webRequestAgentHelperErrorEventArgs = WebRequestAgentHelperErrorEventArgs.Create(m_UnityWebRequest.error); + m_WebRequestAgentHelperErrorEventHandler(this, webRequestAgentHelperErrorEventArgs); + ReferencePool.Release(webRequestAgentHelperErrorEventArgs); + } + else if (m_UnityWebRequest.downloadHandler.isDone) + { + WebRequestAgentHelperCompleteEventArgs webRequestAgentHelperCompleteEventArgs = WebRequestAgentHelperCompleteEventArgs.Create(m_UnityWebRequest.downloadHandler.data); + m_WebRequestAgentHelperCompleteEventHandler(this, webRequestAgentHelperCompleteEventArgs); + ReferencePool.Release(webRequestAgentHelperCompleteEventArgs); + } + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/UnityWebRequestAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/UnityWebRequestAgentHelper.cs.meta new file mode 100644 index 0000000..ad86a1b --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/UnityWebRequestAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e3014b70cd4acd41bed5c829dff3c30 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWFormInfo.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWFormInfo.cs new file mode 100644 index 0000000..c89333c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWFormInfo.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + internal sealed class WWWFormInfo : IReference + { + private WWWForm m_WWWForm; + private object m_UserData; + + public WWWFormInfo() + { + m_WWWForm = null; + m_UserData = null; + } + + public WWWForm WWWForm + { + get + { + return m_WWWForm; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + + public static WWWFormInfo Create(WWWForm wwwForm, object userData) + { + WWWFormInfo wwwFormInfo = ReferencePool.Acquire(); + wwwFormInfo.m_WWWForm = wwwForm; + wwwFormInfo.m_UserData = userData; + return wwwFormInfo; + } + + public void Clear() + { + m_WWWForm = null; + m_UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWFormInfo.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWFormInfo.cs.meta new file mode 100644 index 0000000..0df35db --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWFormInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88d3d7e0a6b8b374783b6dc413adfbd7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWWebRequestAgentHelper.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWWebRequestAgentHelper.cs new file mode 100644 index 0000000..69a5c7f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWWebRequestAgentHelper.cs @@ -0,0 +1,166 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +#if !UNITY_2018_3_OR_NEWER + +using GameFramework; +using GameFramework.WebRequest; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// WWW Web 请求代理辅助器。 + /// + public class WWWWebRequestAgentHelper : WebRequestAgentHelperBase, IDisposable + { + private WWW m_WWW = null; + private bool m_Disposed = false; + + private EventHandler m_WebRequestAgentHelperCompleteEventHandler = null; + private EventHandler m_WebRequestAgentHelperErrorEventHandler = null; + + /// + /// Web 请求代理辅助器完成事件。 + /// + public override event EventHandler WebRequestAgentHelperComplete + { + add + { + m_WebRequestAgentHelperCompleteEventHandler += value; + } + remove + { + m_WebRequestAgentHelperCompleteEventHandler -= value; + } + } + + /// + /// Web 请求代理辅助器错误事件。 + /// + public override event EventHandler WebRequestAgentHelperError + { + add + { + m_WebRequestAgentHelperErrorEventHandler += value; + } + remove + { + m_WebRequestAgentHelperErrorEventHandler -= value; + } + } + + /// + /// 通过 Web 请求代理辅助器发送请求。 + /// + /// 要发送的远程地址。 + /// 用户自定义数据。 + public override void Request(string webRequestUri, object userData) + { + if (m_WebRequestAgentHelperCompleteEventHandler == null || m_WebRequestAgentHelperErrorEventHandler == null) + { + Log.Fatal("Web request agent helper handler is invalid."); + return; + } + + WWWFormInfo wwwFormInfo = (WWWFormInfo)userData; + if (wwwFormInfo.WWWForm == null) + { + m_WWW = new WWW(webRequestUri); + } + else + { + m_WWW = new WWW(webRequestUri, wwwFormInfo.WWWForm); + } + } + + /// + /// 通过 Web 请求代理辅助器发送请求。 + /// + /// 要发送的远程地址。 + /// 要发送的数据流。 + /// 用户自定义数据。 + public override void Request(string webRequestUri, byte[] postData, object userData) + { + if (m_WebRequestAgentHelperCompleteEventHandler == null || m_WebRequestAgentHelperErrorEventHandler == null) + { + Log.Fatal("Web request agent helper handler is invalid."); + return; + } + + m_WWW = new WWW(webRequestUri, postData); + } + + /// + /// 重置 Web 请求代理辅助器。 + /// + public override void Reset() + { + if (m_WWW != null) + { + m_WWW.Dispose(); + m_WWW = null; + } + } + + /// + /// 释放资源。 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 释放资源。 + /// + /// 释放资源标记。 + protected virtual void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_WWW != null) + { + m_WWW.Dispose(); + m_WWW = null; + } + } + + m_Disposed = true; + } + + private void Update() + { + if (m_WWW == null || !m_WWW.isDone) + { + return; + } + + if (!string.IsNullOrEmpty(m_WWW.error)) + { + WebRequestAgentHelperErrorEventArgs webRequestAgentHelperErrorEventArgs = WebRequestAgentHelperErrorEventArgs.Create(m_WWW.error); + m_WebRequestAgentHelperErrorEventHandler(this, webRequestAgentHelperErrorEventArgs); + ReferencePool.Release(webRequestAgentHelperErrorEventArgs); + } + else + { + WebRequestAgentHelperCompleteEventArgs webRequestAgentHelperCompleteEventArgs = WebRequestAgentHelperCompleteEventArgs.Create(m_WWW.bytes); + m_WebRequestAgentHelperCompleteEventHandler(this, webRequestAgentHelperCompleteEventArgs); + ReferencePool.Release(webRequestAgentHelperCompleteEventArgs); + } + } + } +} + +#endif diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWWebRequestAgentHelper.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWWebRequestAgentHelper.cs.meta new file mode 100644 index 0000000..bd828ba --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WWWWebRequestAgentHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58f7b74a3eef2eb478e90ba95fe21d9f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestAgentHelperBase.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestAgentHelperBase.cs new file mode 100644 index 0000000..c52343d --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestAgentHelperBase.cs @@ -0,0 +1,49 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework.WebRequest; +using System; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// Web 请求代理辅助器基类。 + /// + public abstract class WebRequestAgentHelperBase : MonoBehaviour, IWebRequestAgentHelper + { + /// + /// Web 请求代理辅助器完成事件。 + /// + public abstract event EventHandler WebRequestAgentHelperComplete; + + /// + /// Web 请求代理辅助器错误事件。 + /// + public abstract event EventHandler WebRequestAgentHelperError; + + /// + /// 通过 Web 请求代理辅助器发送 Web 请求。 + /// + /// Web 请求地址。 + /// 用户自定义数据。 + public abstract void Request(string webRequestUri, object userData); + + /// + /// 通过 Web 请求代理辅助器发送 Web 请求。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// 用户自定义数据。 + public abstract void Request(string webRequestUri, byte[] postData, object userData); + + /// + /// 重置 Web 请求代理辅助器。 + /// + public abstract void Reset(); + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestAgentHelperBase.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestAgentHelperBase.cs.meta new file mode 100644 index 0000000..b391d02 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestAgentHelperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 435dc9e1aa25c4344b27aa10088d4f1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestComponent.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestComponent.cs new file mode 100644 index 0000000..43682a8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestComponent.cs @@ -0,0 +1,564 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.WebRequest; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityGameFramework.Runtime +{ + /// + /// Web 请求组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Web Request")] + public sealed class WebRequestComponent : GameFrameworkComponent + { + private const int DefaultPriority = 0; + + private IWebRequestManager m_WebRequestManager = null; + private EventComponent m_EventComponent = null; + + [SerializeField] + private Transform m_InstanceRoot = null; + + [SerializeField] + private string m_WebRequestAgentHelperTypeName = "UnityGameFramework.Runtime.UnityWebRequestAgentHelper"; + + [SerializeField] + private WebRequestAgentHelperBase m_CustomWebRequestAgentHelper = null; + + [SerializeField] + private int m_WebRequestAgentHelperCount = 1; + + [SerializeField] + private float m_Timeout = 30f; + + /// + /// 获取 Web 请求代理总数量。 + /// + public int TotalAgentCount + { + get + { + return m_WebRequestManager.TotalAgentCount; + } + } + + /// + /// 获取可用 Web 请求代理数量。 + /// + public int FreeAgentCount + { + get + { + return m_WebRequestManager.FreeAgentCount; + } + } + + /// + /// 获取工作中 Web 请求代理数量。 + /// + public int WorkingAgentCount + { + get + { + return m_WebRequestManager.WorkingAgentCount; + } + } + + /// + /// 获取等待 Web 请求数量。 + /// + public int WaitingTaskCount + { + get + { + return m_WebRequestManager.WaitingTaskCount; + } + } + + /// + /// 获取或设置 Web 请求超时时长,以秒为单位。 + /// + public float Timeout + { + get + { + return m_WebRequestManager.Timeout; + } + set + { + m_WebRequestManager.Timeout = m_Timeout = value; + } + } + + /// + /// 游戏框架组件初始化。 + /// + protected override void Awake() + { + base.Awake(); + + m_WebRequestManager = GameFrameworkEntry.GetModule(); + if (m_WebRequestManager == null) + { + Log.Fatal("Web request manager is invalid."); + return; + } + + m_WebRequestManager.Timeout = m_Timeout; + m_WebRequestManager.WebRequestStart += OnWebRequestStart; + m_WebRequestManager.WebRequestSuccess += OnWebRequestSuccess; + m_WebRequestManager.WebRequestFailure += OnWebRequestFailure; + } + + private void Start() + { + m_EventComponent = GameEntry.GetComponent(); + if (m_EventComponent == null) + { + Log.Fatal("Event component is invalid."); + return; + } + + if (m_InstanceRoot == null) + { + m_InstanceRoot = new GameObject("Web Request Agent Instances").transform; + m_InstanceRoot.SetParent(gameObject.transform); + m_InstanceRoot.localScale = Vector3.one; + } + + for (int i = 0; i < m_WebRequestAgentHelperCount; i++) + { + AddWebRequestAgentHelper(i); + } + } + + /// + /// 根据 Web 请求任务的序列编号获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的序列编号。 + /// Web 请求任务的信息。 + public TaskInfo GetWebRequestInfo(int serialId) + { + return m_WebRequestManager.GetWebRequestInfo(serialId); + } + + /// + /// 根据 Web 请求任务的标签获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的标签。 + /// Web 请求任务的信息。 + public TaskInfo[] GetWebRequestInfos(string tag) + { + return m_WebRequestManager.GetWebRequestInfos(tag); + } + + /// + /// 根据 Web 请求任务的标签获取 Web 请求任务的信息。 + /// + /// 要获取信息的 Web 请求任务的标签。 + /// Web 请求任务的信息。 + public void GetAllWebRequestInfos(string tag, List results) + { + m_WebRequestManager.GetAllWebRequestInfos(tag, results); + } + + /// + /// 获取所有 Web 请求任务的信息。 + /// + /// 所有 Web 请求任务的信息。 + public TaskInfo[] GetAllWebRequestInfos() + { + return m_WebRequestManager.GetAllWebRequestInfos(); + } + + /// + /// 获取所有 Web 请求任务的信息。 + /// + /// 所有 Web 请求任务的信息。 + public void GetAllWebRequestInfos(List results) + { + m_WebRequestManager.GetAllWebRequestInfos(results); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri) + { + return AddWebRequest(webRequestUri, null, null, null, DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData) + { + return AddWebRequest(webRequestUri, postData, null, null, DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// WWW 表单。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, WWWForm wwwForm) + { + return AddWebRequest(webRequestUri, null, wwwForm, null, DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, string tag) + { + return AddWebRequest(webRequestUri, null, null, tag, DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, int priority) + { + return AddWebRequest(webRequestUri, null, null, null, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, object userData) + { + return AddWebRequest(webRequestUri, null, null, null, DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, string tag) + { + return AddWebRequest(webRequestUri, postData, null, tag, DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// WWW 表单。 + /// Web 请求任务的标签。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, WWWForm wwwForm, string tag) + { + return AddWebRequest(webRequestUri, null, wwwForm, tag, DefaultPriority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, int priority) + { + return AddWebRequest(webRequestUri, postData, null, null, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// WWW 表单。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, WWWForm wwwForm, int priority) + { + return AddWebRequest(webRequestUri, null, wwwForm, null, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, object userData) + { + return AddWebRequest(webRequestUri, postData, null, null, DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// WWW 表单。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, WWWForm wwwForm, object userData) + { + return AddWebRequest(webRequestUri, null, wwwForm, null, DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, string tag, int priority) + { + return AddWebRequest(webRequestUri, null, null, tag, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, string tag, object userData) + { + return AddWebRequest(webRequestUri, null, null, tag, DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, int priority, object userData) + { + return AddWebRequest(webRequestUri, null, null, null, priority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, string tag, int priority) + { + return AddWebRequest(webRequestUri, postData, null, tag, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// WWW 表单。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, WWWForm wwwForm, string tag, int priority) + { + return AddWebRequest(webRequestUri, null, wwwForm, tag, priority, null); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, string tag, object userData) + { + return AddWebRequest(webRequestUri, postData, null, tag, DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// WWW 表单。 + /// Web 请求任务的标签。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, WWWForm wwwForm, string tag, object userData) + { + return AddWebRequest(webRequestUri, null, wwwForm, tag, DefaultPriority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, int priority, object userData) + { + return AddWebRequest(webRequestUri, postData, null, null, priority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// WWW 表单。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, WWWForm wwwForm, int priority, object userData) + { + return AddWebRequest(webRequestUri, null, wwwForm, null, priority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, string tag, int priority, object userData) + { + return AddWebRequest(webRequestUri, null, null, tag, priority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, byte[] postData, string tag, int priority, object userData) + { + return AddWebRequest(webRequestUri, postData, null, tag, priority, userData); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// WWW 表单。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + public int AddWebRequest(string webRequestUri, WWWForm wwwForm, string tag, int priority, object userData) + { + return AddWebRequest(webRequestUri, null, wwwForm, tag, priority, userData); + } + + /// + /// 根据 Web 请求任务的序列编号移除 Web 请求任务。 + /// + /// 要移除 Web 请求任务的序列编号。 + /// 是否移除 Web 请求任务成功。 + public bool RemoveWebRequest(int serialId) + { + return m_WebRequestManager.RemoveWebRequest(serialId); + } + + /// + /// 根据 Web 请求任务的标签移除 Web 请求任务。 + /// + /// 要移除 Web 请求任务的标签。 + /// 移除 Web 请求任务的数量。 + public int RemoveWebRequests(string tag) + { + return m_WebRequestManager.RemoveWebRequests(tag); + } + + /// + /// 移除所有 Web 请求任务。 + /// + /// 移除 Web 请求任务的数量。 + public int RemoveAllWebRequests() + { + return m_WebRequestManager.RemoveAllWebRequests(); + } + + /// + /// 增加 Web 请求代理辅助器。 + /// + /// Web 请求代理辅助器索引。 + private void AddWebRequestAgentHelper(int index) + { + WebRequestAgentHelperBase webRequestAgentHelper = Helper.CreateHelper(m_WebRequestAgentHelperTypeName, m_CustomWebRequestAgentHelper, index); + if (webRequestAgentHelper == null) + { + Log.Error("Can not create web request agent helper."); + return; + } + + webRequestAgentHelper.name = Utility.Text.Format("Web Request Agent Helper - {0}", index); + Transform transform = webRequestAgentHelper.transform; + transform.SetParent(m_InstanceRoot); + transform.localScale = Vector3.one; + + m_WebRequestManager.AddWebRequestAgentHelper(webRequestAgentHelper); + } + + /// + /// 增加 Web 请求任务。 + /// + /// Web 请求地址。 + /// 要发送的数据流。 + /// WWW 表单。 + /// Web 请求任务的标签。 + /// Web 请求任务的优先级。 + /// 用户自定义数据。 + /// 新增 Web 请求任务的序列编号。 + private int AddWebRequest(string webRequestUri, byte[] postData, WWWForm wwwForm, string tag, int priority, object userData) + { + return m_WebRequestManager.AddWebRequest(webRequestUri, postData, tag, priority, WWWFormInfo.Create(wwwForm, userData)); + } + + private void OnWebRequestStart(object sender, GameFramework.WebRequest.WebRequestStartEventArgs e) + { + m_EventComponent.Fire(this, WebRequestStartEventArgs.Create(e)); + } + + private void OnWebRequestSuccess(object sender, GameFramework.WebRequest.WebRequestSuccessEventArgs e) + { + m_EventComponent.Fire(this, WebRequestSuccessEventArgs.Create(e)); + } + + private void OnWebRequestFailure(object sender, GameFramework.WebRequest.WebRequestFailureEventArgs e) + { + Log.Warning("Web request failure, web request serial id '{0}', web request uri '{1}', error message '{2}'.", e.SerialId, e.WebRequestUri, e.ErrorMessage); + m_EventComponent.Fire(this, WebRequestFailureEventArgs.Create(e)); + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestComponent.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestComponent.cs.meta new file mode 100644 index 0000000..6bbb4c8 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02988897571ac8b49a59c1a50037bd88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestFailureEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestFailureEventArgs.cs new file mode 100644 index 0000000..46a150f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestFailureEventArgs.cs @@ -0,0 +1,109 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// Web 请求失败事件。 + /// + public sealed class WebRequestFailureEventArgs : GameEventArgs + { + /// + /// Web 请求失败事件编号。 + /// + public static readonly int EventId = typeof(WebRequestFailureEventArgs).GetHashCode(); + + /// + /// 初始化 Web 请求失败事件的新实例。 + /// + public WebRequestFailureEventArgs() + { + SerialId = 0; + WebRequestUri = null; + ErrorMessage = null; + UserData = null; + } + + /// + /// 获取 Web 请求失败事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取 Web 请求任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取 Web 请求地址。 + /// + public string WebRequestUri + { + get; + private set; + } + + /// + /// 获取错误信息。 + /// + public string ErrorMessage + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建 Web 请求失败事件。 + /// + /// 内部事件。 + /// 创建的 Web 请求失败事件。 + public static WebRequestFailureEventArgs Create(GameFramework.WebRequest.WebRequestFailureEventArgs e) + { + WWWFormInfo wwwFormInfo = (WWWFormInfo)e.UserData; + WebRequestFailureEventArgs webRequestFailureEventArgs = ReferencePool.Acquire(); + webRequestFailureEventArgs.SerialId = e.SerialId; + webRequestFailureEventArgs.WebRequestUri = e.WebRequestUri; + webRequestFailureEventArgs.ErrorMessage = e.ErrorMessage; + webRequestFailureEventArgs.UserData = wwwFormInfo.UserData; + ReferencePool.Release(wwwFormInfo); + return webRequestFailureEventArgs; + } + + /// + /// 清理 Web 请求失败事件。 + /// + public override void Clear() + { + SerialId = 0; + WebRequestUri = null; + ErrorMessage = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestFailureEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestFailureEventArgs.cs.meta new file mode 100644 index 0000000..b93a924 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestFailureEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 582d860310370aa47b4fa671963e0200 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestStartEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestStartEventArgs.cs new file mode 100644 index 0000000..2042b0f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestStartEventArgs.cs @@ -0,0 +1,96 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// Web 请求开始事件。 + /// + public sealed class WebRequestStartEventArgs : GameEventArgs + { + /// + /// Web 请求开始事件编号。 + /// + public static readonly int EventId = typeof(WebRequestStartEventArgs).GetHashCode(); + + /// + /// 初始化 Web 请求开始事件的新实例。 + /// + public WebRequestStartEventArgs() + { + SerialId = 0; + WebRequestUri = null; + UserData = null; + } + + /// + /// 获取 Web 请求开始事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取 Web 请求任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取 Web 请求地址。 + /// + public string WebRequestUri + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 创建 Web 请求开始事件。 + /// + /// 内部事件。 + /// 创建的 Web 请求开始事件。 + public static WebRequestStartEventArgs Create(GameFramework.WebRequest.WebRequestStartEventArgs e) + { + WWWFormInfo wwwFormInfo = (WWWFormInfo)e.UserData; + WebRequestStartEventArgs webRequestStartEventArgs = ReferencePool.Acquire(); + webRequestStartEventArgs.SerialId = e.SerialId; + webRequestStartEventArgs.WebRequestUri = e.WebRequestUri; + webRequestStartEventArgs.UserData = wwwFormInfo.UserData; + return webRequestStartEventArgs; + } + + /// + /// 清理 Web 请求开始事件。 + /// + public override void Clear() + { + SerialId = 0; + WebRequestUri = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestStartEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestStartEventArgs.cs.meta new file mode 100644 index 0000000..6007375 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestStartEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f73533092cec3d498691d5805a8f856 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestSuccessEventArgs.cs b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestSuccessEventArgs.cs new file mode 100644 index 0000000..915967c --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestSuccessEventArgs.cs @@ -0,0 +1,111 @@ +//------------------------------------------------------------ +// Game Framework +// Copyright © 2013-2021 Jiang Yin. All rights reserved. +// Homepage: https://gameframework.cn/ +// Feedback: mailto:ellan@gameframework.cn +//------------------------------------------------------------ + +using GameFramework; +using GameFramework.Event; + +namespace UnityGameFramework.Runtime +{ + /// + /// Web 请求成功事件。 + /// + public sealed class WebRequestSuccessEventArgs : GameEventArgs + { + private byte[] m_WebResponseBytes = null; + + /// + /// Web 请求成功事件编号。 + /// + public static readonly int EventId = typeof(WebRequestSuccessEventArgs).GetHashCode(); + + /// + /// 初始化 Web 请求成功事件的新实例。 + /// + public WebRequestSuccessEventArgs() + { + SerialId = 0; + WebRequestUri = null; + m_WebResponseBytes = null; + UserData = null; + } + + /// + /// 获取 Web 请求成功事件编号。 + /// + public override int Id + { + get + { + return EventId; + } + } + + /// + /// 获取 Web 请求任务的序列编号。 + /// + public int SerialId + { + get; + private set; + } + + /// + /// 获取 Web 请求地址。 + /// + public string WebRequestUri + { + get; + private set; + } + + /// + /// 获取用户自定义数据。 + /// + public object UserData + { + get; + private set; + } + + /// + /// 获取 Web 响应的数据流。 + /// + /// Web 响应的数据流。 + public byte[] GetWebResponseBytes() + { + return m_WebResponseBytes; + } + + /// + /// 创建 Web 请求成功事件。 + /// + /// 内部事件。 + /// 创建的 Web 请求成功事件。 + public static WebRequestSuccessEventArgs Create(GameFramework.WebRequest.WebRequestSuccessEventArgs e) + { + WWWFormInfo wwwFormInfo = (WWWFormInfo)e.UserData; + WebRequestSuccessEventArgs webRequestSuccessEventArgs = ReferencePool.Acquire(); + webRequestSuccessEventArgs.SerialId = e.SerialId; + webRequestSuccessEventArgs.WebRequestUri = e.WebRequestUri; + webRequestSuccessEventArgs.m_WebResponseBytes = e.GetWebResponseBytes(); + webRequestSuccessEventArgs.UserData = wwwFormInfo.UserData; + ReferencePool.Release(wwwFormInfo); + return webRequestSuccessEventArgs; + } + + /// + /// 清理 Web 请求成功事件。 + /// + public override void Clear() + { + SerialId = 0; + WebRequestUri = null; + m_WebResponseBytes = null; + UserData = null; + } + } +} diff --git a/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestSuccessEventArgs.cs.meta b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestSuccessEventArgs.cs.meta new file mode 100644 index 0000000..d545c35 --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/Runtime/UnityGameFramework/WebRequest/WebRequestSuccessEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 12523ea48f6be044592256bf32605f5d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.bywaystudios.gameframework/package.json b/Packages/com.bywaystudios.gameframework/package.json new file mode 100644 index 0000000..3577b8e --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/package.json @@ -0,0 +1,6 @@ +{ + "name": "com.bywaystudios.gameframework", + "displayName": "GameFramework", + "version": "0.1.0", + "description": "Custom GameFramework code" +} \ No newline at end of file diff --git a/Packages/com.bywaystudios.gameframework/package.json.meta b/Packages/com.bywaystudios.gameframework/package.json.meta new file mode 100644 index 0000000..33a4d4f --- /dev/null +++ b/Packages/com.bywaystudios.gameframework/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d7134fc52ccdf1240a2f118533f0bc5b +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/manifest.json b/Packages/manifest.json new file mode 100644 index 0000000..2f4ec86 --- /dev/null +++ b/Packages/manifest.json @@ -0,0 +1,39 @@ +{ + "dependencies": { + "com.unity.asset-store-validation": "0.6.0", + "com.unity.feature.development": "1.0.1", + "com.unity.ugui": "1.0.0", + "com.unity.upm.develop": "0.5.3-exp.1", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.cloth": "1.0.0", + "com.unity.modules.director": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vehicles": "1.0.0", + "com.unity.modules.video": "1.0.0", + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.wind": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } +} diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json new file mode 100644 index 0000000..050dee8 --- /dev/null +++ b/Packages/packages-lock.json @@ -0,0 +1,377 @@ +{ + "dependencies": { + "com.bywaystudios.gameframework": { + "version": "file:com.bywaystudios.gameframework", + "depth": 0, + "source": "embedded", + "dependencies": {} + }, + "com.unity.asset-store-validation": { + "version": "0.6.0", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.nuget.newtonsoft-json": "2.0.2" + }, + "url": "https://packages.unity.com" + }, + "com.unity.editorcoroutines": { + "version": "1.0.0", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.ext.nunit": { + "version": "1.0.6", + "depth": 2, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.feature.development": { + "version": "1.0.1", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.ide.visualstudio": "2.0.22", + "com.unity.ide.rider": "3.0.36", + "com.unity.ide.vscode": "1.2.5", + "com.unity.editorcoroutines": "1.0.0", + "com.unity.performance.profile-analyzer": "1.2.3", + "com.unity.test-framework": "1.1.33", + "com.unity.testtools.codecoverage": "1.2.6" + } + }, + "com.unity.ide.rider": { + "version": "3.0.36", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ide.visualstudio": { + "version": "2.0.22", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.1.9" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ide.vscode": { + "version": "1.2.5", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.nuget.newtonsoft-json": { + "version": "3.2.1", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.performance.profile-analyzer": { + "version": "1.2.3", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.settings-manager": { + "version": "2.1.0", + "depth": 2, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.test-framework": { + "version": "1.1.33", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.testtools.codecoverage": { + "version": "1.2.6", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.0.16", + "com.unity.settings-manager": "1.0.1" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ugui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0" + } + }, + "com.unity.upm.develop": { + "version": "0.5.3-exp.1", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.1.20", + "com.unity.nuget.newtonsoft-json": "2.0.2", + "com.unity.asset-store-validation": "0.1.3" + }, + "url": "https://packages.unity.com" + }, + "com.unity.modules.ai": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.androidjni": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.animation": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.assetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.audio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.cloth": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.director": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.animation": "1.0.0" + } + }, + "com.unity.modules.imageconversion": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.imgui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.jsonserialize": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.particlesystem": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics2d": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.screencapture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.subsystems": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.terrain": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.terrainphysics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.terrain": "1.0.0" + } + }, + "com.unity.modules.tilemap": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics2d": "1.0.0" + } + }, + "com.unity.modules.ui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.uielements": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.umbra": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unityanalytics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.unitywebrequest": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unitywebrequestassetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestaudio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.audio": "1.0.0" + } + }, + "com.unity.modules.unitywebrequesttexture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestwww": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.vehicles": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.video": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.vr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } + }, + "com.unity.modules.wind": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.xr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.subsystems": "1.0.0" + } + } + } +} diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..07ebfb0 --- /dev/null +++ b/ProjectSettings/AudioManager.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 + m_RequestedDSPBufferSize: 1024 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..e7886b2 --- /dev/null +++ b/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..cdc1f3e --- /dev/null +++ b/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 0 + m_ReuseCollisionCallbacks: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 + m_FrictionType: 0 + m_EnableEnhancedDeterminism: 0 + m_EnableUnifiedHeightmaps: 1 + m_DefaultMaxAngluarSpeed: 7 diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..0147887 --- /dev/null +++ b/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: [] + m_configObjects: {} diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..1e44a0a --- /dev/null +++ b/ProjectSettings/EditorSettings.asset @@ -0,0 +1,30 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 0 + m_DefaultBehaviorMode: 0 + m_PrefabRegularEnvironment: {fileID: 0} + m_PrefabUIEnvironment: {fileID: 0} + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref + m_ProjectGenerationRootNamespace: + m_CollabEditorSettings: + inProgressEnabled: 1 + m_EnableTextureStreamingInEditMode: 1 + m_EnableTextureStreamingInPlayMode: 1 + m_AsyncShaderCompilation: 1 + m_EnterPlayModeOptionsEnabled: 0 + m_EnterPlayModeOptions: 3 + m_ShowLightmapResolutionOverlay: 1 + m_UseLegacyProbeSampleCount: 0 + m_SerializeInlineMappingsOnOneLine: 1 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..43369e3 --- /dev/null +++ b/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,63 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 13 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 + m_LogWhenShaderIsCompiled: 0 + m_AllowEnlightenSupportForUpgradedProject: 0 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..17c8f53 --- /dev/null +++ b/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/ProjectSettings/MemorySettings.asset b/ProjectSettings/MemorySettings.asset new file mode 100644 index 0000000..5b5face --- /dev/null +++ b/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: {} diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..3b0b7c3 --- /dev/null +++ b/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/ProjectSettings/PackageManagerSettings.asset b/ProjectSettings/PackageManagerSettings.asset new file mode 100644 index 0000000..112a053 --- /dev/null +++ b/ProjectSettings/PackageManagerSettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 61 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_EnablePreReleasePackages: 0 + m_EnablePackageDependencies: 0 + m_AdvancedSettingsExpanded: 1 + m_ScopedRegistriesSettingsExpanded: 1 + m_SeeAllPackageVersions: 0 + oneTimeWarningShown: 0 + m_Registries: + - m_Id: main + m_Name: + m_Url: https://packages.unity.com + m_Scopes: [] + m_IsDefault: 1 + m_Capabilities: 7 + m_UserSelectedRegistryName: + m_UserAddingNewScopedRegistry: 0 + m_RegistryInfoDraft: + m_Modified: 0 + m_ErrorMessage: + m_UserModificationsInstanceId: -830 + m_OriginalInstanceId: -832 + m_LoadAssets: 0 diff --git a/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json b/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json new file mode 100644 index 0000000..3c7b4c1 --- /dev/null +++ b/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json @@ -0,0 +1,5 @@ +{ + "m_Dictionary": { + "m_DictionaryValues": [] + } +} \ No newline at end of file diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..47880b1 --- /dev/null +++ b/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,56 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 4 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_ReuseCollisionCallbacks: 1 + m_AutoSyncTransforms: 0 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/ProjectSettings/PresetManager.asset b/ProjectSettings/PresetManager.asset new file mode 100644 index 0000000..67a94da --- /dev/null +++ b/ProjectSettings/PresetManager.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_DefaultPresets: {} diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..f64042b --- /dev/null +++ b/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,865 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 26 + productGUID: 2d3c6e7a81db8c14f8d725a38940fe89 + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: ResourceLoaderPackage + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1920 + defaultScreenHeight: 1080 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 1 + unsupportedMSAAFallback: 0 + m_SpriteBatchVertexThreshold: 300 + m_MTRendering: 1 + mipStripping: 0 + numberOfMipsStripped: 0 + numberOfMipsStrippedPerMipmapLimitGroup: {} + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosUseCustomAppBackgroundBehavior: 0 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidUseSwappy: 1 + androidBlitType: 0 + androidResizableWindow: 0 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 + androidAutoRotationBehavior: 1 + androidPredictiveBackSupport: 1 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + audioSpatialExperience: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + dedicatedServerOptimizations: 0 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + useFlipModelSwapchain: 1 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 1 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOneEnableTypeOptimization: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + switchGpuScratchPoolGranularity: 2097152 + switchAllowGpuScratchShrinking: 0 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + switchNVNGraphicsFirmwareMemory: 32 + switchMaxWorkerMultiple: 8 + stadiaPresentMode: 0 + stadiaTargetFramerate: 0 + vulkanNumSwapchainBuffers: 3 + vulkanEnableSetSRGBWrite: 0 + vulkanEnablePreTransform: 1 + vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 + loadStoreDebugModeEnabled: 0 + visionOSBundleVersion: 1.0 + tvOSBundleVersion: 1.0 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 1 + xboxOneEnable7thCore: 1 + vrSettings: + enable360StereoCapture: 0 + isWsaHolographicRemotingEnabled: 0 + enableFrameTimingStats: 0 + enableOpenGLProfilerGPURecorders: 1 + allowHDRDisplaySupport: 0 + useHDRDisplay: 0 + hdrBitDepth: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + resetResolutionOnWindowResize: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: + Standalone: com.DefaultCompany.ResourceLoaderPackage + buildNumber: + Standalone: 0 + VisionOS: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 0 + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 22 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + strictShaderVariantMatching: 0 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSSimulatorArchitecture: 0 + iOSTargetOSVersionString: 12.0 + tvOSSdkVersion: 0 + tvOSSimulatorArchitecture: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 12.0 + VisionOSSdkVersion: 0 + VisionOSTargetOSVersionString: 1.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + macOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + metalCompileShaderBinary: 0 + iOSRenderExtraFrameOnPause: 0 + iosCopyPluginsCodeInsteadOfSymlink: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + VisionOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + VisionOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + shaderPrecisionModel: 0 + clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea + templatePackageId: com.unity.template.3d@8.1.3 + templateDefaultScene: Assets/Scenes/SampleScene.unity + useCustomMainManifest: 0 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 0 + useCustomLauncherGradleManifest: 0 + useCustomBaseGradleTemplate: 0 + useCustomGradlePropertiesTemplate: 0 + useCustomGradleSettingsTemplate: 0 + useCustomProguardFile: 0 + AndroidTargetArchitectures: 1 + AndroidTargetDevices: 0 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidEnableArmv9SecurityFeatures: 0 + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 0 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + chromeosInputEmulation: 1 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 150 + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 0 + m_SubKind: + m_BuildTargetBatching: + - m_BuildTarget: Standalone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: tvOS + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: Android + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: iPhone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: WebGL + m_StaticBatching: 0 + m_DynamicBatching: 0 + m_BuildTargetShaderSettings: [] + m_BuildTargetGraphicsJobs: + - m_BuildTarget: MacStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: Switch + m_GraphicsJobs: 1 + - m_BuildTarget: MetroSupport + m_GraphicsJobs: 1 + - m_BuildTarget: AppleTVSupport + m_GraphicsJobs: 0 + - m_BuildTarget: BJMSupport + m_GraphicsJobs: 1 + - m_BuildTarget: LinuxStandaloneSupport + m_GraphicsJobs: 1 + - m_BuildTarget: PS4Player + m_GraphicsJobs: 1 + - m_BuildTarget: iOSSupport + m_GraphicsJobs: 0 + - m_BuildTarget: WindowsStandaloneSupport + m_GraphicsJobs: 1 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobs: 1 + - m_BuildTarget: LuminSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AndroidPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: WebGLSupport + m_GraphicsJobs: 0 + m_BuildTargetGraphicsJobMode: + - m_BuildTarget: PS4Player + m_GraphicsJobMode: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobMode: 0 + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: AndroidPlayer + m_APIs: 150000000b000000 + m_Automatic: 1 + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: AppleTVSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: WebGLSupport + m_APIs: 0b000000 + m_Automatic: 1 + m_BuildTargetVRSettings: + - m_BuildTarget: Standalone + m_Enabled: 0 + m_Devices: + - Oculus + - OpenVR + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + openGLRequireES32: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: + - m_BuildTarget: Android + m_EncodingQuality: 1 + - m_BuildTarget: iPhone + m_EncodingQuality: 1 + - m_BuildTarget: tvOS + m_EncodingQuality: 1 + m_BuildTargetGroupHDRCubemapEncodingQuality: + - m_BuildTarget: Android + m_EncodingQuality: 1 + - m_BuildTarget: iPhone + m_EncodingQuality: 1 + - m_BuildTarget: tvOS + m_EncodingQuality: 1 + m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetGroupLoadStoreDebugModeSettings: [] + m_BuildTargetNormalMapEncoding: + - m_BuildTarget: Android + m_Encoding: 1 + - m_BuildTarget: iPhone + m_Encoding: 1 + - m_BuildTarget: tvOS + m_Encoding: 1 + m_BuildTargetDefaultTextureCompressionFormat: + - m_BuildTarget: Android + m_Format: 3 + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + bluetoothUsageDescription: + macOSTargetOSVersion: 10.13.0 + switchNMETAOverride: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchEnableFileSystemTrace: 0 + switchLTOSetting: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchCompilerFlags: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchTitleNames_15: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchPublisherNames_15: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchRatingsInt_12: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 22 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchDisableHTCSPlayerConnection: 0 + switchUseNewStyleFilepaths: 1 + switchUseLegacyFmodPriorities: 0 + switchUseMicroSleepForYield: 1 + switchEnableRamDiskSupport: 0 + switchMicroSleepForYieldTime: 25 + switchRamDiskSpaceSize: 12 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4AllowPS5Detection: 0 + ps4GPU800MHz: 1 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 + spritePackerPolicy: + webGLMemorySize: 16 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLShowDiagnostics: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLDecompressionFallback: 0 + webGLInitialMemorySize: 32 + webGLMaximumMemorySize: 2048 + webGLMemoryGrowthMode: 2 + webGLMemoryLinearGrowthStep: 16 + webGLMemoryGeometricGrowthStep: 0.2 + webGLMemoryGeometricGrowthCap: 96 + webGLPowerPreference: 2 + scriptingDefineSymbols: {} + additionalCompilerArguments: {} + platformArchitecture: {} + scriptingBackend: {} + il2cppCompilerConfiguration: {} + il2cppCodeGeneration: {} + managedStrippingLevel: + EmbeddedLinux: 1 + GameCoreScarlett: 1 + GameCoreXboxOne: 1 + Nintendo Switch: 1 + PS4: 1 + PS5: 1 + QNX: 1 + Stadia: 1 + VisionOS: 1 + WebGL: 1 + Windows Store Apps: 1 + XboxOne: 1 + iPhone: 1 + tvOS: 1 + incrementalIl2cppBuild: {} + suppressCommonWarnings: 1 + allowUnsafeCode: 0 + useDeterministicCompilation: 1 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 1 + gcWBarrierValidation: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: ResourceLoaderPackage + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: ResourceLoaderPackage + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} + metroSplashScreenUseBackgroundColor: 0 + syncCapabilities: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + vcxProjDefaultLanguage: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnhancedXboxCompatibilityMode: 0 + XboxOneEnableGPUVariability: 1 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: + vrEditorSettings: {} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + hmiPlayerDataPath: + hmiForceSRGBBlit: 1 + embeddedLinuxEnableGamepadInput: 1 + hmiLogStartupTiming: 0 + hmiCpuConfiguration: + apiCompatibilityLevel: 6 + activeInputHandler: 0 + windowsGamepadBackendHint: 0 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] + projectName: + organizationId: + cloudEnabled: 0 + legacyClampBlendShapeWeights: 0 + hmiLoadingImage: {fileID: 0} + platformRequiresReadableAssets: 0 + virtualTexturingSupportEnabled: 0 + insecureHttpOption: 0 diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..587f809 --- /dev/null +++ b/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 2022.3.62f3 +m_EditorVersionWithRevision: 2022.3.62f3 (96770f904ca7) diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..36c0dad --- /dev/null +++ b/ProjectSettings/QualitySettings.asset @@ -0,0 +1,234 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 5 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Lumin: 5 + GameCoreScarlett: 5 + GameCoreXboxOne: 5 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PS5: 5 + Stadia: 5 + Standalone: 5 + WebGL: 3 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..1c92a78 --- /dev/null +++ b/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..558a017 --- /dev/null +++ b/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..a88bee0 --- /dev/null +++ b/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,36 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 0 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_DashboardUrl: https://dashboard.unity3d.com + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com + m_Enabled: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_TestMode: 0 + m_InitializeOnStartup: 1 + m_PackageRequiringCoreStatsPresent: 0 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/ProjectSettings/VFXManager.asset b/ProjectSettings/VFXManager.asset new file mode 100644 index 0000000..3a95c98 --- /dev/null +++ b/ProjectSettings/VFXManager.asset @@ -0,0 +1,12 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_StripUpdateShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 diff --git a/ProjectSettings/VersionControlSettings.asset b/ProjectSettings/VersionControlSettings.asset new file mode 100644 index 0000000..dca2881 --- /dev/null +++ b/ProjectSettings/VersionControlSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!890905787 &1 +VersionControlSettings: + m_ObjectHideFlags: 0 + m_Mode: Visible Meta Files + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/ProjectSettings/XRSettings.asset b/ProjectSettings/XRSettings.asset new file mode 100644 index 0000000..482590c --- /dev/null +++ b/ProjectSettings/XRSettings.asset @@ -0,0 +1,10 @@ +{ + "m_SettingKeys": [ + "VR Device Disabled", + "VR Device User Alert" + ], + "m_SettingValues": [ + "False", + "False" + ] +} \ No newline at end of file