//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 loyalsoft. All rights reserved.
// Homepage: http://www.game7000.com/
// Feedback: http://www.game7000.com/
//------------------------------------------------------------
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));
}
}
}
}