框架大更新
1.进步优化UI系统 加载问题 性能问题 Canvas重绘问题 边界处理问题 2.优化对象池和游戏对象池的性能 游戏对象池根据窗口 策略定期清理 3.优化整个AppService 和ServiceWorld结构 固定三大类 具体参考代码
This commit is contained in:
parent
9bcf20ad6a
commit
6397cc03b2
485
Editor/Localization/LocalizationAiWriteTool.cs
Normal file
485
Editor/Localization/LocalizationAiWriteTool.cs
Normal file
@ -0,0 +1,485 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using AlicizaX.Localization.Runtime;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace AlicizaX.Localization.Editor
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public sealed class LocalizationAiWriteRequest
|
||||||
|
{
|
||||||
|
public string TableAssetPath;
|
||||||
|
public string SectionName = "AI";
|
||||||
|
public string Key;
|
||||||
|
public bool AllowUpdate = true;
|
||||||
|
public bool AutoCreateSection = true;
|
||||||
|
public bool AutoCreateLanguageAsset = true;
|
||||||
|
public bool FillMissingLanguagesWithEmpty = true;
|
||||||
|
public bool SaveAssets = true;
|
||||||
|
public bool HotReloadWhenPlaying = true;
|
||||||
|
public List<LocalizationAiTranslation> Translations = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class LocalizationAiTranslation
|
||||||
|
{
|
||||||
|
public string Language;
|
||||||
|
public string Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class LocalizationAiWriteResult
|
||||||
|
{
|
||||||
|
public bool Success;
|
||||||
|
public string TableAssetPath;
|
||||||
|
public string SectionName;
|
||||||
|
public string Key;
|
||||||
|
public string RuntimeKey;
|
||||||
|
public bool CreatedSection;
|
||||||
|
public bool CreatedEntry;
|
||||||
|
public bool HotReloaded;
|
||||||
|
public List<string> UpdatedLanguages = new();
|
||||||
|
public List<string> Warnings = new();
|
||||||
|
public string Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LocalizationAiWriteTool
|
||||||
|
{
|
||||||
|
private const string DefaultSectionName = "AI";
|
||||||
|
private const string LastSelectedTableKey = "LastSelectedGameLocaizationTable";
|
||||||
|
|
||||||
|
public static LocalizationAiWriteResult Execute(LocalizationAiWriteRequest request)
|
||||||
|
{
|
||||||
|
LocalizationAiWriteResult result = new();
|
||||||
|
if (request == null)
|
||||||
|
{
|
||||||
|
result.Message = "Request is null.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string tablePath = request.TableAssetPath;
|
||||||
|
if (string.IsNullOrWhiteSpace(tablePath))
|
||||||
|
{
|
||||||
|
tablePath = EditorPrefs.GetString(LastSelectedTableKey, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(tablePath))
|
||||||
|
{
|
||||||
|
result.Message = "TableAssetPath is empty.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameLocaizationTable table = AssetDatabase.LoadAssetAtPath<GameLocaizationTable>(tablePath);
|
||||||
|
if (table == null)
|
||||||
|
{
|
||||||
|
result.Message = $"Can not load GameLocaizationTable from path: {tablePath}";
|
||||||
|
result.TableAssetPath = tablePath;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.TableAssetPath = tablePath;
|
||||||
|
|
||||||
|
string sectionName = request.SectionName;
|
||||||
|
string itemKey = request.Key;
|
||||||
|
ParseAndNormalizeKey(ref sectionName, ref itemKey);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(sectionName))
|
||||||
|
{
|
||||||
|
sectionName = DefaultSectionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(itemKey))
|
||||||
|
{
|
||||||
|
result.Message = "Key is empty after normalization.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table.TableSheet == null)
|
||||||
|
{
|
||||||
|
table.TableSheet = new List<GameLocaizationTable.TableData>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table.Languages == null)
|
||||||
|
{
|
||||||
|
table.Languages = new List<LocalizationLanguage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int sectionIndex = FindSectionIndex(table, sectionName);
|
||||||
|
if (sectionIndex < 0)
|
||||||
|
{
|
||||||
|
if (!request.AutoCreateSection)
|
||||||
|
{
|
||||||
|
result.Message = $"Section '{sectionName}' does not exist.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameLocaizationTable.TableData newSection = new(sectionName, GenerateUniqueSectionId(table));
|
||||||
|
table.TableSheet.Add(newSection);
|
||||||
|
sectionIndex = table.TableSheet.Count - 1;
|
||||||
|
result.CreatedSection = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameLocaizationTable.TableData section = table.TableSheet[sectionIndex];
|
||||||
|
if (section.SectionSheet == null)
|
||||||
|
{
|
||||||
|
section.SectionSheet = new List<GameLocaizationTable.SheetItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int entryIndex = FindEntryIndex(section, itemKey);
|
||||||
|
bool createdEntry = false;
|
||||||
|
if (entryIndex < 0)
|
||||||
|
{
|
||||||
|
GameLocaizationTable.SheetItem newItem = new(itemKey, GenerateUniqueEntryId(table), true);
|
||||||
|
section.SectionSheet.Add(newItem);
|
||||||
|
entryIndex = section.SectionSheet.Count - 1;
|
||||||
|
createdEntry = true;
|
||||||
|
result.CreatedEntry = true;
|
||||||
|
}
|
||||||
|
else if (!request.AllowUpdate)
|
||||||
|
{
|
||||||
|
result.Message = $"Key '{itemKey}' already exists in section '{sectionName}'.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameLocaizationTable.SheetItem entry = section.SectionSheet[entryIndex];
|
||||||
|
string runtimeKey = BuildRuntimeKey(section.SectionName, entry.Key);
|
||||||
|
|
||||||
|
Dictionary<string, string> translationMap = BuildTranslationMap(request.Translations, result.Warnings);
|
||||||
|
EnsureEntryExistsForAllLanguages(table, section, entry, runtimeKey, translationMap, request, result);
|
||||||
|
|
||||||
|
table.TableSheet[sectionIndex] = section;
|
||||||
|
|
||||||
|
table.InvalidateLanguageLookup();
|
||||||
|
EditorUtility.SetDirty(table);
|
||||||
|
if (request.SaveAssets)
|
||||||
|
{
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.HotReloadWhenPlaying &&
|
||||||
|
Application.isPlaying &&
|
||||||
|
AppServices.TryGet<ILocalizationService>(out var localizationService))
|
||||||
|
{
|
||||||
|
localizationService.ReloadLocalizationConfig(table);
|
||||||
|
result.HotReloaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Success = true;
|
||||||
|
result.SectionName = section.SectionName;
|
||||||
|
result.Key = entry.Key;
|
||||||
|
result.RuntimeKey = runtimeKey;
|
||||||
|
result.Message = createdEntry
|
||||||
|
? $"Added localization entry '{runtimeKey}'."
|
||||||
|
: $"Updated localization entry '{runtimeKey}'.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ExecuteJson(string json)
|
||||||
|
{
|
||||||
|
LocalizationAiWriteRequest request = Utility.Json.ToObject<LocalizationAiWriteRequest>(json);
|
||||||
|
LocalizationAiWriteResult result = Execute(request);
|
||||||
|
return Utility.Json.ToJson(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureEntryExistsForAllLanguages(
|
||||||
|
GameLocaizationTable table,
|
||||||
|
GameLocaizationTable.TableData section,
|
||||||
|
GameLocaizationTable.SheetItem entry,
|
||||||
|
string runtimeKey,
|
||||||
|
Dictionary<string, string> translationMap,
|
||||||
|
LocalizationAiWriteRequest request,
|
||||||
|
LocalizationAiWriteResult result)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < table.Languages.Count; i++)
|
||||||
|
{
|
||||||
|
LocalizationLanguage language = table.Languages[i];
|
||||||
|
if (language == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpsertLanguageEntry(
|
||||||
|
language,
|
||||||
|
section.Id,
|
||||||
|
entry.Id,
|
||||||
|
runtimeKey,
|
||||||
|
translationMap.TryGetValue(language.LanguageName, out string text) ? text : string.Empty,
|
||||||
|
translationMap.ContainsKey(language.LanguageName) || request.FillMissingLanguagesWithEmpty);
|
||||||
|
|
||||||
|
EditorUtility.SetDirty(language);
|
||||||
|
result.UpdatedLanguages.Add(language.LanguageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> pair in translationMap)
|
||||||
|
{
|
||||||
|
if (HasLanguage(table, pair.Key))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request.AutoCreateLanguageAsset)
|
||||||
|
{
|
||||||
|
result.Warnings.Add($"Language asset '{pair.Key}' does not exist in table '{table.name}'.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalizationLanguage language = CreateLanguageAsset(table, pair.Key);
|
||||||
|
UpsertLanguageEntry(language, section.Id, entry.Id, runtimeKey, pair.Value, true);
|
||||||
|
EditorUtility.SetDirty(language);
|
||||||
|
result.UpdatedLanguages.Add(language.LanguageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpsertLanguageEntry(
|
||||||
|
LocalizationLanguage language,
|
||||||
|
int sectionId,
|
||||||
|
int entryId,
|
||||||
|
string runtimeKey,
|
||||||
|
string value,
|
||||||
|
bool shouldWrite)
|
||||||
|
{
|
||||||
|
if (language.Strings == null)
|
||||||
|
{
|
||||||
|
language.Strings = new List<LocalizationLanguage.LocalizationString>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = FindLanguageStringIndex(language, sectionId, entryId);
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
LocalizationLanguage.LocalizationString item = language.Strings[index];
|
||||||
|
item.Key = runtimeKey;
|
||||||
|
if (shouldWrite)
|
||||||
|
{
|
||||||
|
item.Value = value ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
language.Strings[index] = item;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shouldWrite)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
language.Strings.Add(new LocalizationLanguage.LocalizationString
|
||||||
|
{
|
||||||
|
SectionId = sectionId,
|
||||||
|
EntryId = entryId,
|
||||||
|
Key = runtimeKey,
|
||||||
|
Value = value ?? string.Empty
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalizationLanguage CreateLanguageAsset(GameLocaizationTable table, string languageName)
|
||||||
|
{
|
||||||
|
LocalizationLanguage language = ScriptableObject.CreateInstance<LocalizationLanguage>();
|
||||||
|
language.name = languageName;
|
||||||
|
language.LanguageName = languageName;
|
||||||
|
language.Strings = new List<LocalizationLanguage.LocalizationString>();
|
||||||
|
AssetDatabase.AddObjectToAsset(language, table);
|
||||||
|
table.Languages.Add(language);
|
||||||
|
table.InvalidateLanguageLookup();
|
||||||
|
EditorUtility.SetDirty(table);
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, string> BuildTranslationMap(
|
||||||
|
List<LocalizationAiTranslation> translations,
|
||||||
|
List<string> warnings)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> map = new(StringComparer.Ordinal);
|
||||||
|
if (translations == null)
|
||||||
|
{
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < translations.Count; i++)
|
||||||
|
{
|
||||||
|
LocalizationAiTranslation translation = translations[i];
|
||||||
|
if (translation == null || string.IsNullOrWhiteSpace(translation.Language))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string normalizedLanguage = NormalizePart(translation.Language);
|
||||||
|
if (string.IsNullOrEmpty(normalizedLanguage))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map.ContainsKey(normalizedLanguage))
|
||||||
|
{
|
||||||
|
warnings.Add($"Duplicate language '{normalizedLanguage}' found. Last value wins.");
|
||||||
|
}
|
||||||
|
|
||||||
|
map[normalizedLanguage] = translation.Text ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool HasLanguage(GameLocaizationTable table, string languageName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < table.Languages.Count; i++)
|
||||||
|
{
|
||||||
|
LocalizationLanguage language = table.Languages[i];
|
||||||
|
if (language != null && string.Equals(language.LanguageName, languageName, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FindSectionIndex(GameLocaizationTable table, string sectionName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < table.TableSheet.Count; i++)
|
||||||
|
{
|
||||||
|
if (string.Equals(table.TableSheet[i].SectionName, sectionName, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FindEntryIndex(GameLocaizationTable.TableData section, string itemKey)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < section.SectionSheet.Count; i++)
|
||||||
|
{
|
||||||
|
if (string.Equals(section.SectionSheet[i].Key, itemKey, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FindLanguageStringIndex(LocalizationLanguage language, int sectionId, int entryId)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < language.Strings.Count; i++)
|
||||||
|
{
|
||||||
|
LocalizationLanguage.LocalizationString item = language.Strings[i];
|
||||||
|
if (item.SectionId == sectionId && item.EntryId == entryId)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GenerateUniqueSectionId(GameLocaizationTable table)
|
||||||
|
{
|
||||||
|
return GenerateUniqueId(table, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GenerateUniqueEntryId(GameLocaizationTable table)
|
||||||
|
{
|
||||||
|
return GenerateUniqueId(table, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GenerateUniqueId(GameLocaizationTable table, bool checkSectionIds)
|
||||||
|
{
|
||||||
|
int candidate = Mathf.Abs(Guid.NewGuid().GetHashCode());
|
||||||
|
while (candidate == 0 || ContainsId(table, candidate, checkSectionIds))
|
||||||
|
{
|
||||||
|
candidate = Mathf.Abs(Guid.NewGuid().GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ContainsId(GameLocaizationTable table, int id, bool checkSectionIds)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < table.TableSheet.Count; i++)
|
||||||
|
{
|
||||||
|
GameLocaizationTable.TableData section = table.TableSheet[i];
|
||||||
|
if (checkSectionIds && section.Id == id)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (section.SectionSheet == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < section.SectionSheet.Count; j++)
|
||||||
|
{
|
||||||
|
if (!checkSectionIds && section.SectionSheet[j].Id == id)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildRuntimeKey(string sectionName, string itemKey)
|
||||||
|
{
|
||||||
|
return string.Concat(sectionName, ".", itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ParseAndNormalizeKey(ref string sectionName, ref string itemKey)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(itemKey))
|
||||||
|
{
|
||||||
|
int separatorIndex = itemKey.IndexOf('.');
|
||||||
|
if (separatorIndex > 0 && separatorIndex < itemKey.Length - 1)
|
||||||
|
{
|
||||||
|
sectionName = itemKey.Substring(0, separatorIndex);
|
||||||
|
itemKey = itemKey.Substring(separatorIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionName = NormalizePart(sectionName);
|
||||||
|
itemKey = NormalizePart(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizePart(string value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder builder = new(value.Length);
|
||||||
|
for (int i = 0; i < value.Length; i++)
|
||||||
|
{
|
||||||
|
char current = value[i];
|
||||||
|
if (char.IsLetterOrDigit(current) || current == '_')
|
||||||
|
{
|
||||||
|
builder.Append(current);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char.IsWhiteSpace(current) || current == '-' || current == '/')
|
||||||
|
{
|
||||||
|
builder.Append('_');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (builder.Length > 0 && builder[0] == '_')
|
||||||
|
{
|
||||||
|
builder.Remove(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (builder.Length > 0 && builder[builder.Length - 1] == '_')
|
||||||
|
{
|
||||||
|
builder.Remove(builder.Length - 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
11
Editor/Localization/LocalizationAiWriteTool.cs.meta
Normal file
11
Editor/Localization/LocalizationAiWriteTool.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 511aa2d0442ccf746aa6dd266d5197d6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -1,11 +1,25 @@
|
|||||||
namespace AlicizaX
|
namespace AlicizaX
|
||||||
{
|
{
|
||||||
/// <summary>
|
public static class ServiceDomainOrder
|
||||||
/// 框架内置的 App Scope 标记类,生命周期与 ServiceWorld 相同。
|
{
|
||||||
/// </summary>
|
public const int App = -10000;
|
||||||
|
public const int Scene = -5000;
|
||||||
|
public const int Gameplay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class AppScope : IScope
|
public sealed class AppScope : IScope
|
||||||
{
|
{
|
||||||
public int Order => -10000;
|
public int Order => ServiceDomainOrder.App;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class SceneScope : IScope
|
||||||
|
{
|
||||||
|
public int Order => ServiceDomainOrder.Scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class GameplayScope : IScope
|
||||||
|
{
|
||||||
|
public int Order => ServiceDomainOrder.Gameplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IScope
|
public interface IScope
|
||||||
|
|||||||
@ -7,6 +7,8 @@ namespace AlicizaX
|
|||||||
private static ServiceWorld _world;
|
private static ServiceWorld _world;
|
||||||
|
|
||||||
public static bool HasWorld => _world != null;
|
public static bool HasWorld => _world != null;
|
||||||
|
public static bool HasScene => _world != null && _world.HasScene;
|
||||||
|
public static bool HasGameplay => _world != null && _world.HasGameplay;
|
||||||
|
|
||||||
public static ServiceWorld World
|
public static ServiceWorld World
|
||||||
{
|
{
|
||||||
@ -18,36 +20,45 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ServiceScope App => World.AppScope;
|
public static ServiceScope App => World.App;
|
||||||
|
|
||||||
public static ServiceWorld EnsureWorld(int appScopeOrder = -10000)
|
public static ServiceScope Scene => World.Scene;
|
||||||
|
|
||||||
|
public static ServiceScope Gameplay => World.Gameplay;
|
||||||
|
|
||||||
|
public static ServiceWorld EnsureWorld(int appScopeOrder = ServiceDomainOrder.App)
|
||||||
{
|
{
|
||||||
if (_world == null)
|
if (_world == null)
|
||||||
_world = new ServiceWorld(appScopeOrder);
|
_world = new ServiceWorld(appScopeOrder);
|
||||||
return _world;
|
return _world;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Scope 管理 ──────────────────────────────────────────────────────────
|
public static ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene)
|
||||||
|
=> World.EnsureScene(order);
|
||||||
|
|
||||||
public static ServiceScope CreateScope<TScope>(int order = 0) where TScope : IScope
|
public static bool TryGetScene(out ServiceScope scope)
|
||||||
=> World.CreateScope<TScope>(order);
|
|
||||||
|
|
||||||
public static ServiceScope GetOrCreateScope<TScope>(int order = 0) where TScope : IScope
|
|
||||||
=> World.GetOrCreateScope<TScope>(order);
|
|
||||||
|
|
||||||
public static bool TryGetScope<TScope>(out ServiceScope scope) where TScope : IScope
|
|
||||||
{
|
{
|
||||||
if (_world == null) { scope = null; return false; }
|
if (_world == null) { scope = null; return false; }
|
||||||
return _world.TryGetScope<TScope>(out scope);
|
return _world.TryGetScene(out scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool DestroyScope<TScope>() where TScope : IScope
|
public static ServiceScope ResetScene(int order = ServiceDomainOrder.Scene)
|
||||||
|
=> World.ResetScene(order);
|
||||||
|
|
||||||
|
public static bool DestroyScene()
|
||||||
|
=> _world != null && _world.DestroyScene();
|
||||||
|
|
||||||
|
public static ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay)
|
||||||
|
=> World.EnsureGameplay(order);
|
||||||
|
|
||||||
|
public static bool TryGetGameplay(out ServiceScope scope)
|
||||||
{
|
{
|
||||||
if (_world == null) return false;
|
if (_world == null) { scope = null; return false; }
|
||||||
return _world.DestroyScope<TScope>();
|
return _world.TryGetGameplay(out scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Service 查找 ────────────────────────────────────────────────────────
|
public static bool DestroyGameplay()
|
||||||
|
=> _world != null && _world.DestroyGameplay();
|
||||||
|
|
||||||
public static bool TryGet<T>(out T service) where T : class, IService
|
public static bool TryGet<T>(out T service) where T : class, IService
|
||||||
{
|
{
|
||||||
@ -58,8 +69,6 @@ namespace AlicizaX
|
|||||||
public static T Require<T>() where T : class, IService
|
public static T Require<T>() where T : class, IService
|
||||||
=> World.Require<T>();
|
=> World.Require<T>();
|
||||||
|
|
||||||
// ── 生命周期 ────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
public static void Shutdown()
|
public static void Shutdown()
|
||||||
{
|
{
|
||||||
if (_world == null) return;
|
if (_world == null) return;
|
||||||
|
|||||||
@ -12,7 +12,17 @@ namespace AlicizaX
|
|||||||
|
|
||||||
public ServiceScope Scope { get; }
|
public ServiceScope Scope { get; }
|
||||||
|
|
||||||
public ServiceScope AppScope => World.AppScope;
|
public ServiceScope App => World.App;
|
||||||
|
|
||||||
|
public ServiceScope AppScope => App;
|
||||||
|
|
||||||
|
public bool HasScene => World.HasScene;
|
||||||
|
|
||||||
|
public bool HasGameplay => World.HasGameplay;
|
||||||
|
|
||||||
|
public ServiceScope Scene => World.Scene;
|
||||||
|
|
||||||
|
public ServiceScope Gameplay => World.Gameplay;
|
||||||
|
|
||||||
public T Require<T>() where T : class, IService
|
public T Require<T>() where T : class, IService
|
||||||
=> World.Require<T>(Scope);
|
=> World.Require<T>(Scope);
|
||||||
@ -20,13 +30,28 @@ namespace AlicizaX
|
|||||||
public bool TryGet<T>(out T service) where T : class, IService
|
public bool TryGet<T>(out T service) where T : class, IService
|
||||||
=> World.TryGet(Scope, out service);
|
=> World.TryGet(Scope, out service);
|
||||||
|
|
||||||
public ServiceScope CreateScope<TScope>(int order = 0) where TScope : IScope
|
public ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene)
|
||||||
=> World.CreateScope<TScope>(order);
|
=> World.EnsureScene(order);
|
||||||
|
|
||||||
public ServiceScope GetOrCreateScope<TScope>(int order = 0) where TScope : IScope
|
public bool TryGetScene(out ServiceScope scope)
|
||||||
=> World.GetOrCreateScope<TScope>(order);
|
=> World.TryGetScene(out scope);
|
||||||
|
|
||||||
public bool TryGetScope<TScope>(out ServiceScope scope) where TScope : IScope
|
public ServiceScope ResetScene(int order = ServiceDomainOrder.Scene)
|
||||||
=> World.TryGetScope<TScope>(out scope);
|
=> World.ResetScene(order);
|
||||||
|
|
||||||
|
public ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay)
|
||||||
|
=> World.EnsureGameplay(order);
|
||||||
|
|
||||||
|
public bool TryGetGameplay(out ServiceScope scope)
|
||||||
|
=> World.TryGetGameplay(out scope);
|
||||||
|
|
||||||
|
public T RequireApp<T>() where T : class, IService
|
||||||
|
=> App.Require<T>();
|
||||||
|
|
||||||
|
public T RequireScene<T>() where T : class, IService
|
||||||
|
=> Scene.Require<T>();
|
||||||
|
|
||||||
|
public T RequireGameplay<T>() where T : class, IService
|
||||||
|
=> Gameplay.Require<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,58 +10,89 @@ namespace AlicizaX
|
|||||||
|
|
||||||
private ServiceScope[] _scopeSnapshot = Array.Empty<ServiceScope>();
|
private ServiceScope[] _scopeSnapshot = Array.Empty<ServiceScope>();
|
||||||
private bool _scopesDirty;
|
private bool _scopesDirty;
|
||||||
|
private ServiceScope _sceneScope;
|
||||||
|
private ServiceScope _gameplayScope;
|
||||||
|
|
||||||
public ServiceWorld(int appScopeOrder = -10000)
|
public ServiceWorld(int appScopeOrder = ServiceDomainOrder.App)
|
||||||
{
|
{
|
||||||
AppScope = CreateScopeInternal(typeof(AppScope), appScopeOrder);
|
App = CreateScopeInternal(typeof(AppScope), nameof(AppScope), appScopeOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceScope AppScope { get; }
|
public ServiceScope App { get; }
|
||||||
|
|
||||||
// ── Scope 管理(Type-based) ────────────────────────────────────────────
|
public ServiceScope AppScope => App;
|
||||||
|
|
||||||
public ServiceScope CreateScope<TScope>(int order = 0) where TScope : IScope
|
public bool HasScene => _sceneScope != null && !_sceneScope.IsDisposed;
|
||||||
|
|
||||||
|
public bool HasGameplay => _gameplayScope != null && !_gameplayScope.IsDisposed;
|
||||||
|
|
||||||
|
public ServiceScope Scene
|
||||||
{
|
{
|
||||||
var type = typeof(TScope);
|
get
|
||||||
if (_scopesByType.ContainsKey(type))
|
{
|
||||||
throw new InvalidOperationException($"Scope {type.Name} already exists.");
|
if (!HasScene)
|
||||||
return CreateScopeInternal(type, order);
|
throw new InvalidOperationException("Scene scope has not been created yet.");
|
||||||
|
return _sceneScope;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceScope GetOrCreateScope<TScope>(int order = 0) where TScope : IScope
|
public ServiceScope Gameplay
|
||||||
{
|
{
|
||||||
var type = typeof(TScope);
|
get
|
||||||
if (_scopesByType.TryGetValue(type, out var existing))
|
{
|
||||||
return existing;
|
if (!HasGameplay)
|
||||||
return CreateScopeInternal(type, order);
|
throw new InvalidOperationException("Gameplay scope has not been created yet.");
|
||||||
|
return _gameplayScope;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetScope<TScope>(out ServiceScope scope) where TScope : IScope
|
public ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene)
|
||||||
=> _scopesByType.TryGetValue(typeof(TScope), out scope);
|
=> _sceneScope is { IsDisposed: false }
|
||||||
|
? _sceneScope
|
||||||
|
: _sceneScope = CreateScopeInternal(typeof(SceneScope), nameof(SceneScope), order);
|
||||||
|
|
||||||
public ServiceScope GetScope<TScope>() where TScope : IScope
|
public bool TryGetScene(out ServiceScope scope)
|
||||||
{
|
{
|
||||||
if (TryGetScope<TScope>(out var scope)) return scope;
|
scope = HasScene ? _sceneScope : null;
|
||||||
throw new InvalidOperationException($"Scope {typeof(TScope).Name} does not exist.");
|
return scope != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DestroyScope<TScope>() where TScope : IScope
|
public ServiceScope ResetScene(int order = ServiceDomainOrder.Scene)
|
||||||
{
|
{
|
||||||
if (typeof(TScope) == typeof(AppScope))
|
DestroyScene();
|
||||||
throw new InvalidOperationException("AppScope can only be destroyed when the world is disposed.");
|
return EnsureScene(order);
|
||||||
|
}
|
||||||
|
|
||||||
var type = typeof(TScope);
|
public bool DestroyScene()
|
||||||
if (!_scopesByType.TryGetValue(type, out var scope))
|
{
|
||||||
|
if (!HasScene)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_scopesByType.Remove(type);
|
var scope = _sceneScope;
|
||||||
_scopes.Remove(scope);
|
_sceneScope = null;
|
||||||
_scopesDirty = true;
|
return DestroyScope(scope, typeof(SceneScope));
|
||||||
scope.Dispose();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Service 查找 ────────────────────────────────────────────────────────
|
public ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay)
|
||||||
|
=> _gameplayScope is { IsDisposed: false }
|
||||||
|
? _gameplayScope
|
||||||
|
: _gameplayScope = CreateScopeInternal(typeof(GameplayScope), nameof(GameplayScope), order);
|
||||||
|
|
||||||
|
public bool TryGetGameplay(out ServiceScope scope)
|
||||||
|
{
|
||||||
|
scope = HasGameplay ? _gameplayScope : null;
|
||||||
|
return scope != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DestroyGameplay()
|
||||||
|
{
|
||||||
|
if (!HasGameplay)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var scope = _gameplayScope;
|
||||||
|
_gameplayScope = null;
|
||||||
|
return DestroyScope(scope, typeof(GameplayScope));
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryGet<T>(out T service) where T : class, IService
|
public bool TryGet<T>(out T service) where T : class, IService
|
||||||
=> TryGet(null, out service);
|
=> TryGet(null, out service);
|
||||||
@ -91,8 +122,6 @@ namespace AlicizaX
|
|||||||
throw new InvalidOperationException($"Service {typeof(T).FullName} was not found in any active scope.");
|
throw new InvalidOperationException($"Service {typeof(T).FullName} was not found in any active scope.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Tick ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
public void Tick(float deltaTime)
|
public void Tick(float deltaTime)
|
||||||
{
|
{
|
||||||
var snapshot = GetScopeSnapshot();
|
var snapshot = GetScopeSnapshot();
|
||||||
@ -117,23 +146,37 @@ namespace AlicizaX
|
|||||||
for (var i = 0; i < snapshot.Length; i++) snapshot[i].DrawGizmos();
|
for (var i = 0; i < snapshot.Length; i++) snapshot[i].DrawGizmos();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Dispose ─────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
var snapshot = _scopes.ToArray();
|
var snapshot = _scopes.ToArray();
|
||||||
for (var i = snapshot.Length - 1; i >= 0; i--)
|
for (var i = snapshot.Length - 1; i >= 0; i--)
|
||||||
snapshot[i].Dispose();
|
snapshot[i].Dispose();
|
||||||
|
|
||||||
|
_sceneScope = null;
|
||||||
|
_gameplayScope = null;
|
||||||
_scopes.Clear();
|
_scopes.Clear();
|
||||||
_scopesByType.Clear();
|
_scopesByType.Clear();
|
||||||
_scopeSnapshot = Array.Empty<ServiceScope>();
|
_scopeSnapshot = Array.Empty<ServiceScope>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 内部 ────────────────────────────────────────────────────────────────
|
private bool DestroyScope(ServiceScope scope, Type scopeType)
|
||||||
|
|
||||||
private ServiceScope CreateScopeInternal(Type scopeType, int order)
|
|
||||||
{
|
{
|
||||||
var scope = new ServiceScope(this, scopeType.Name, order);
|
if (scope == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_scopesByType.Remove(scopeType);
|
||||||
|
_scopes.Remove(scope);
|
||||||
|
_scopesDirty = true;
|
||||||
|
scope.Dispose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServiceScope CreateScopeInternal(Type scopeType, string scopeName, int order)
|
||||||
|
{
|
||||||
|
if (_scopesByType.ContainsKey(scopeType))
|
||||||
|
throw new InvalidOperationException($"Scope {scopeType.Name} already exists.");
|
||||||
|
|
||||||
|
var scope = new ServiceScope(this, scopeName, order);
|
||||||
_scopes.Add(scope);
|
_scopes.Add(scope);
|
||||||
_scopesByType.Add(scopeType, scope);
|
_scopesByType.Add(scopeType, scope);
|
||||||
_scopes.Sort(CompareScopeOrder);
|
_scopes.Sort(CompareScopeOrder);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace AlicizaX
|
|||||||
private static AppServiceRoot s_activeRoot;
|
private static AppServiceRoot s_activeRoot;
|
||||||
|
|
||||||
[SerializeField] private bool _dontDestroyOnLoad = true;
|
[SerializeField] private bool _dontDestroyOnLoad = true;
|
||||||
[SerializeField] private int _appScopeOrder = -10000;
|
[SerializeField] private int _appScopeOrder = ServiceDomainOrder.App;
|
||||||
|
|
||||||
private bool _ownsWorld;
|
private bool _ownsWorld;
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ namespace AlicizaX
|
|||||||
_ownsWorld = createdWorld;
|
_ownsWorld = createdWorld;
|
||||||
|
|
||||||
if (createdWorld)
|
if (createdWorld)
|
||||||
RegisterAppServices(world.AppScope);
|
RegisterAppServices(world.App);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Update()
|
protected virtual void Update()
|
||||||
|
|||||||
@ -2,9 +2,6 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace AlicizaX
|
namespace AlicizaX
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Mono 服务基类(不自动注册,适合需要手动控制注册时机的场景)。
|
|
||||||
/// </summary>
|
|
||||||
public abstract class MonoServiceBehaviour : MonoBehaviour, IMonoService
|
public abstract class MonoServiceBehaviour : MonoBehaviour, IMonoService
|
||||||
{
|
{
|
||||||
public ServiceContext Context { get; private set; }
|
public ServiceContext Context { get; private set; }
|
||||||
@ -39,25 +36,11 @@ namespace AlicizaX
|
|||||||
protected virtual void OnDestroyService() { }
|
protected virtual void OnDestroyService() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mono 服务基类(自动注册到 <typeparamref name="TScope"/>)。
|
|
||||||
/// <para>
|
|
||||||
/// 场景服务:<c>_dontDestroyOnLoad = false</c>(默认),销毁时自动注销。<br/>
|
|
||||||
/// 跨场景服务:<c>_dontDestroyOnLoad = true</c>,首个实例持久化并注册;
|
|
||||||
/// 后续场景中出现的重复实例自动销毁自身。
|
|
||||||
/// </para>
|
|
||||||
/// <para>
|
|
||||||
/// 子类通过 <see cref="OnAwake"/> 执行额外的 Awake 逻辑,
|
|
||||||
/// 通过 <see cref="OnServiceInitialize"/> 执行注册后的初始化,
|
|
||||||
/// 通过 <see cref="OnServiceDestroy"/> 执行注销前的清理。
|
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
|
||||||
public abstract class MonoServiceBehaviour<TScope> : MonoServiceBehaviour
|
public abstract class MonoServiceBehaviour<TScope> : MonoServiceBehaviour
|
||||||
where TScope : IScope
|
where TScope : IScope
|
||||||
{
|
{
|
||||||
[SerializeField] private bool _dontDestroyOnLoad = false;
|
[SerializeField] private bool _dontDestroyOnLoad = false;
|
||||||
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
OnAwake();
|
OnAwake();
|
||||||
@ -65,9 +48,8 @@ namespace AlicizaX
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
var scope = AppServices.GetOrCreateScope<TScope>();
|
var scope = ResolveOrCreateScope();
|
||||||
|
|
||||||
// 跨场景重复实例检测:契约已被占用则销毁自身
|
|
||||||
if (scope.HasContract(GetType()))
|
if (scope.HasContract(GetType()))
|
||||||
{
|
{
|
||||||
Destroy(gameObject);
|
Destroy(gameObject);
|
||||||
@ -84,15 +66,43 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
if (!IsInitialized) return;
|
if (!IsInitialized) return;
|
||||||
if (!AppServices.HasWorld) return;
|
if (!AppServices.HasWorld) return;
|
||||||
if (!AppServices.TryGetScope<TScope>(out var scope)) return;
|
if (!TryResolveScope(out var scope)) return;
|
||||||
|
|
||||||
scope.Unregister(this);
|
scope.Unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private static ServiceScope ResolveOrCreateScope()
|
||||||
/// 在 Awake 阶段执行(早于 Start 中的自动注册)。
|
{
|
||||||
/// 适合缓存组件引用等不依赖服务系统的初始化。
|
if (typeof(TScope) == typeof(AppScope))
|
||||||
/// </summary>
|
return AppServices.App;
|
||||||
|
|
||||||
|
if (typeof(TScope) == typeof(SceneScope))
|
||||||
|
return AppServices.EnsureScene();
|
||||||
|
|
||||||
|
if (typeof(TScope) == typeof(GameplayScope))
|
||||||
|
return AppServices.EnsureGameplay();
|
||||||
|
|
||||||
|
throw new System.InvalidOperationException($"Unsupported service scope: {typeof(TScope).FullName}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryResolveScope(out ServiceScope scope)
|
||||||
|
{
|
||||||
|
if (typeof(TScope) == typeof(AppScope))
|
||||||
|
{
|
||||||
|
scope = AppServices.App;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof(TScope) == typeof(SceneScope))
|
||||||
|
return AppServices.TryGetScene(out scope);
|
||||||
|
|
||||||
|
if (typeof(TScope) == typeof(GameplayScope))
|
||||||
|
return AppServices.TryGetGameplay(out scope);
|
||||||
|
|
||||||
|
scope = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void OnAwake() { }
|
protected virtual void OnAwake() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,8 @@ namespace AlicizaX
|
|||||||
private UniTask _initializeTask;
|
private UniTask _initializeTask;
|
||||||
private bool _initializationCompleted;
|
private bool _initializationCompleted;
|
||||||
private Exception _initializationException;
|
private Exception _initializationException;
|
||||||
private float _lastCleanupTime;
|
private bool _cleanupScheduled;
|
||||||
|
private float _nextCleanupTime = float.MaxValue;
|
||||||
|
|
||||||
private bool _isShuttingDown;
|
private bool _isShuttingDown;
|
||||||
|
|
||||||
@ -51,11 +52,14 @@ namespace AlicizaX
|
|||||||
_shutdownTokenSource = new CancellationTokenSource();
|
_shutdownTokenSource = new CancellationTokenSource();
|
||||||
EnsureDefaultResourceLoaders();
|
EnsureDefaultResourceLoaders();
|
||||||
EnsurePoolContainer();
|
EnsurePoolContainer();
|
||||||
|
enabled = false;
|
||||||
|
Application.lowMemory += OnLowMemory;
|
||||||
_initializeTask = InitializeAsync(_shutdownTokenSource.Token);
|
_initializeTask = InitializeAsync(_shutdownTokenSource.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDestroyService()
|
protected override void OnDestroyService()
|
||||||
{
|
{
|
||||||
|
Application.lowMemory -= OnLowMemory;
|
||||||
_shutdownTokenSource?.Cancel();
|
_shutdownTokenSource?.Cancel();
|
||||||
ClearAllPools();
|
ClearAllPools();
|
||||||
|
|
||||||
@ -75,9 +79,9 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
await UniTask.WaitUntil(() => YooAsset.YooAssets.Initialized, cancellationToken: cancellationToken);
|
await UniTask.WaitUntil(() => YooAsset.YooAssets.Initialized, cancellationToken: cancellationToken);
|
||||||
LoadConfigs();
|
LoadConfigs();
|
||||||
_lastCleanupTime = Time.time;
|
|
||||||
_initializationCompleted = true;
|
_initializationCompleted = true;
|
||||||
await PrewarmConfiguredPoolsAsync(cancellationToken);
|
await PrewarmConfiguredPoolsAsync(cancellationToken);
|
||||||
|
ScheduleCleanup();
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
@ -92,18 +96,19 @@ namespace AlicizaX
|
|||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (!IsReady)
|
if (!IsReady || !_cleanupScheduled)
|
||||||
{
|
{
|
||||||
|
enabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Time.time - _lastCleanupTime < checkInterval)
|
if (Time.time < _nextCleanupTime)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformCleanup();
|
PerformCleanup();
|
||||||
_lastCleanupTime = Time.time;
|
ScheduleCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetResourceLoader(IResourceLoader resourceLoader)
|
public void SetResourceLoader(IResourceLoader resourceLoader)
|
||||||
@ -205,7 +210,7 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
|
|
||||||
PerformCleanup();
|
PerformCleanup();
|
||||||
_lastCleanupTime = Time.time;
|
ScheduleCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearAllPools()
|
public void ClearAllPools()
|
||||||
@ -224,6 +229,9 @@ namespace AlicizaX
|
|||||||
_resolvedConfigCache.Clear();
|
_resolvedConfigCache.Clear();
|
||||||
_groupLoaderCache.Clear();
|
_groupLoaderCache.Clear();
|
||||||
ReleaseDebugSnapshots();
|
ReleaseDebugSnapshots();
|
||||||
|
_cleanupScheduled = false;
|
||||||
|
_nextCleanupTime = float.MaxValue;
|
||||||
|
enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GameObjectPoolSnapshot> GetDebugSnapshots()
|
public List<GameObjectPoolSnapshot> GetDebugSnapshots()
|
||||||
@ -248,6 +256,7 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ownersByObject[gameObject] = pool;
|
_ownersByObject[gameObject] = pool;
|
||||||
|
NotifyPoolStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UnregisterOwnedObject(GameObject gameObject)
|
internal void UnregisterOwnedObject(GameObject gameObject)
|
||||||
@ -258,6 +267,17 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ownersByObject.Remove(gameObject);
|
_ownersByObject.Remove(gameObject);
|
||||||
|
NotifyPoolStateChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void NotifyPoolStateChanged()
|
||||||
|
{
|
||||||
|
if (!IsReady)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScheduleCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private GameObject GetGameObjectInternal(string assetPath, string group, Transform parent)
|
private GameObject GetGameObjectInternal(string assetPath, string group, Transform parent)
|
||||||
@ -347,6 +367,7 @@ namespace AlicizaX
|
|||||||
_shutdownTokenSource != null ? _shutdownTokenSource.Token : default);
|
_shutdownTokenSource != null ? _shutdownTokenSource.Token : default);
|
||||||
|
|
||||||
_poolsByKey.Add(poolKey, pool);
|
_poolsByKey.Add(poolKey, pool);
|
||||||
|
ScheduleCleanup();
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,6 +380,43 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ScheduleCleanup()
|
||||||
|
{
|
||||||
|
if (!IsReady)
|
||||||
|
{
|
||||||
|
_cleanupScheduled = false;
|
||||||
|
_nextCleanupTime = float.MaxValue;
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float nextDueTime = float.MaxValue;
|
||||||
|
float now = Time.time;
|
||||||
|
foreach (RuntimePrefabPool pool in _poolsByKey.Values)
|
||||||
|
{
|
||||||
|
float candidate = pool.GetNextCleanupTime(now, checkInterval);
|
||||||
|
if (candidate < nextDueTime)
|
||||||
|
{
|
||||||
|
nextDueTime = candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_nextCleanupTime = nextDueTime;
|
||||||
|
_cleanupScheduled = nextDueTime < float.MaxValue;
|
||||||
|
enabled = _cleanupScheduled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLowMemory()
|
||||||
|
{
|
||||||
|
if (!IsReady)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformCleanup();
|
||||||
|
ScheduleCleanup();
|
||||||
|
}
|
||||||
|
|
||||||
private void EnsureDefaultResourceLoaders()
|
private void EnsureDefaultResourceLoaders()
|
||||||
{
|
{
|
||||||
if (!_resourceLoaders.ContainsKey(PoolResourceLoaderType.AssetBundle))
|
if (!_resourceLoaders.ContainsKey(PoolResourceLoaderType.AssetBundle))
|
||||||
|
|||||||
@ -16,18 +16,51 @@ namespace AlicizaX
|
|||||||
|
|
||||||
public class UnityResourcesLoader : IResourceLoader
|
public class UnityResourcesLoader : IResourceLoader
|
||||||
{
|
{
|
||||||
|
private static bool AllowLegacyResourcesFallback => Application.isEditor || Debug.isDebugBuild;
|
||||||
|
|
||||||
public GameObject LoadPrefab(string location)
|
public GameObject LoadPrefab(string location)
|
||||||
{
|
{
|
||||||
return Resources.Load<GameObject>(location);
|
if (TryGetResourceService(out var resourceService))
|
||||||
|
{
|
||||||
|
var prefab = resourceService.LoadAsset<GameObject>(location);
|
||||||
|
if (prefab != null)
|
||||||
|
{
|
||||||
|
return prefab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AllowLegacyResourcesFallback ? Resources.Load<GameObject>(location) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async UniTask<GameObject> LoadPrefabAsync(string location, CancellationToken cancellationToken = default)
|
public async UniTask<GameObject> LoadPrefabAsync(string location, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await Resources.LoadAsync<GameObject>(location).ToUniTask(cancellationToken: cancellationToken) as GameObject;
|
if (TryGetResourceService(out var resourceService))
|
||||||
|
{
|
||||||
|
var prefab = await resourceService.LoadAssetAsync<GameObject>(location, cancellationToken);
|
||||||
|
if (prefab != null)
|
||||||
|
{
|
||||||
|
return prefab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AllowLegacyResourcesFallback
|
||||||
|
? await Resources.LoadAsync<GameObject>(location).ToUniTask(cancellationToken: cancellationToken) as GameObject
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameObject LoadGameObject(string location, Transform parent = null)
|
public GameObject LoadGameObject(string location, Transform parent = null)
|
||||||
{
|
{
|
||||||
|
if (TryGetResourceService(out var resourceService))
|
||||||
|
{
|
||||||
|
var managedObject = resourceService.LoadGameObject(location, parent);
|
||||||
|
if (managedObject != null)
|
||||||
|
{
|
||||||
|
return managedObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AllowLegacyResourcesFallback) return null;
|
||||||
|
|
||||||
var prefab = Resources.Load<GameObject>(location);
|
var prefab = Resources.Load<GameObject>(location);
|
||||||
if (prefab == null) return null;
|
if (prefab == null) return null;
|
||||||
|
|
||||||
@ -42,6 +75,17 @@ namespace AlicizaX
|
|||||||
|
|
||||||
public async UniTask<GameObject> LoadGameObjectAsync(string location, Transform parent = null, CancellationToken cancellationToken = default)
|
public async UniTask<GameObject> LoadGameObjectAsync(string location, Transform parent = null, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
if (TryGetResourceService(out var resourceService))
|
||||||
|
{
|
||||||
|
var managedObject = await resourceService.LoadGameObjectAsync(location, parent, cancellationToken);
|
||||||
|
if (managedObject != null)
|
||||||
|
{
|
||||||
|
return managedObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AllowLegacyResourcesFallback) return null;
|
||||||
|
|
||||||
var prefab = await Resources.LoadAsync<GameObject>(location).ToUniTask(cancellationToken: cancellationToken) as GameObject;
|
var prefab = await Resources.LoadAsync<GameObject>(location).ToUniTask(cancellationToken: cancellationToken) as GameObject;
|
||||||
if (prefab == null) return null;
|
if (prefab == null) return null;
|
||||||
|
|
||||||
@ -59,6 +103,11 @@ namespace AlicizaX
|
|||||||
// Resources.UnloadAsset cannot unload GameObjects.
|
// Resources.UnloadAsset cannot unload GameObjects.
|
||||||
// The prefab reference is nulled by the caller; Unity handles cleanup via UnloadUnusedAssets.
|
// The prefab reference is nulled by the caller; Unity handles cleanup via UnloadUnusedAssets.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool TryGetResourceService(out IResourceService resourceService)
|
||||||
|
{
|
||||||
|
return AppServices.TryGet(out resourceService);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AssetBundleResourceLoader : IResourceLoader
|
public class AssetBundleResourceLoader : IResourceLoader
|
||||||
|
|||||||
@ -241,6 +241,7 @@ namespace AlicizaX
|
|||||||
|
|
||||||
instance.InactiveNode = _inactiveInstances.AddLast(instance);
|
instance.InactiveNode = _inactiveInstances.AddLast(instance);
|
||||||
TouchPrefab();
|
TouchPrefab();
|
||||||
|
_service.NotifyPoolStateChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +282,34 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float GetNextCleanupTime(float now, float fallbackDelay)
|
||||||
|
{
|
||||||
|
float nextDueTime = float.MaxValue;
|
||||||
|
|
||||||
|
if (_config.instanceIdleTimeout > 0f && _inactiveInstances.First != null)
|
||||||
|
{
|
||||||
|
float instanceDueTime = _inactiveInstances.First.Value.LastReleaseTime + _config.instanceIdleTimeout;
|
||||||
|
nextDueTime = Math.Min(nextDueTime, Math.Max(now, instanceDueTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_prefab != null &&
|
||||||
|
_instancesByObject.Count == 0 &&
|
||||||
|
_config.prefabUnloadDelay > 0f)
|
||||||
|
{
|
||||||
|
float prefabDueTime = _lastPrefabTouchTime + _config.prefabUnloadDelay;
|
||||||
|
nextDueTime = Math.Min(nextDueTime, Math.Max(now, prefabDueTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextDueTime < float.MaxValue)
|
||||||
|
{
|
||||||
|
return nextDueTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _instancesByObject.Count > 0 || _prefab != null
|
||||||
|
? now + Math.Max(fallbackDelay, 0.1f)
|
||||||
|
: float.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
public GameObjectPoolSnapshot CreateSnapshot()
|
public GameObjectPoolSnapshot CreateSnapshot()
|
||||||
{
|
{
|
||||||
var snapshot = MemoryPool.Acquire<GameObjectPoolSnapshot>();
|
var snapshot = MemoryPool.Acquire<GameObjectPoolSnapshot>();
|
||||||
@ -489,6 +518,7 @@ namespace AlicizaX
|
|||||||
transform.localScale = Vector3.one;
|
transform.localScale = Vector3.one;
|
||||||
instance.GameObject.SetActive(false);
|
instance.GameObject.SetActive(false);
|
||||||
instance.InactiveNode = _inactiveInstances.AddLast(instance);
|
instance.InactiveNode = _inactiveInstances.AddLast(instance);
|
||||||
|
_service.NotifyPoolStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DestroyInstance(RuntimePooledInstance instance)
|
private void DestroyInstance(RuntimePooledInstance instance)
|
||||||
@ -528,6 +558,7 @@ namespace AlicizaX
|
|||||||
_instancesByObject.Remove(gameObject);
|
_instancesByObject.Remove(gameObject);
|
||||||
_service.UnregisterOwnedObject(gameObject);
|
_service.UnregisterOwnedObject(gameObject);
|
||||||
TouchPrefab();
|
TouchPrefab();
|
||||||
|
_service.NotifyPoolStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveInactiveNode(RuntimePooledInstance instance)
|
private void RemoveInactiveNode(RuntimePooledInstance instance)
|
||||||
|
|||||||
@ -9,9 +9,9 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
public class ModuleDynamicBind : MonoBehaviour
|
public class ModuleDynamicBind : MonoBehaviour
|
||||||
{
|
{
|
||||||
[FormerlySerializedAs("_resourceServiceBehaviour")] [SerializeField] private ResourceComponent resourceComponent;
|
[SerializeField] private ResourceComponent resourceComponent;
|
||||||
[FormerlySerializedAs("_debuggerServiceBehaviour")] [SerializeField] private DebuggerComponent debuggerComponent;
|
[SerializeField] private DebuggerComponent debuggerComponent;
|
||||||
[FormerlySerializedAs("_localizationServiceBehaviour")] [SerializeField] private LocalizationComponent localizationComponent;
|
[SerializeField] private LocalizationComponent localizationComponent;
|
||||||
private ModuleDynamicBindInfo _dynamicBindInfo;
|
private ModuleDynamicBindInfo _dynamicBindInfo;
|
||||||
|
|
||||||
private void OnValidate()
|
private void OnValidate()
|
||||||
@ -24,7 +24,23 @@ namespace AlicizaX
|
|||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
if (Application.isEditor) return;
|
if (Application.isEditor) return;
|
||||||
TextAsset text = Resources.Load<TextAsset>("ModuleDynamicBindInfo");
|
TextAsset text = null;
|
||||||
|
if (AppServices.TryGet<IResourceService>(out var resourceService))
|
||||||
|
{
|
||||||
|
text = resourceService.LoadAsset<TextAsset>("ModuleDynamicBindInfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text == null)
|
||||||
|
{
|
||||||
|
text = Resources.Load<TextAsset>("ModuleDynamicBindInfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text == null)
|
||||||
|
{
|
||||||
|
Log.Warning("ModuleDynamicBindInfo not found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_dynamicBindInfo = Utility.Json.ToObject<ModuleDynamicBindInfo>(text.text);
|
_dynamicBindInfo = Utility.Json.ToObject<ModuleDynamicBindInfo>(text.text);
|
||||||
|
|
||||||
if (resourceComponent != null)
|
if (resourceComponent != null)
|
||||||
|
|||||||
@ -1,745 +1,80 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using AlicizaX;
|
using AlicizaX;
|
||||||
|
|
||||||
namespace AlicizaX.ObjectPool
|
namespace AlicizaX.ObjectPool
|
||||||
{
|
{
|
||||||
|
public readonly struct ObjectPoolCreateOptions
|
||||||
|
{
|
||||||
|
public readonly string Name;
|
||||||
|
public readonly bool AllowMultiSpawn;
|
||||||
|
public readonly float AutoReleaseInterval;
|
||||||
|
public readonly int Capacity;
|
||||||
|
public readonly float ExpireTime;
|
||||||
|
public readonly int Priority;
|
||||||
|
|
||||||
|
public ObjectPoolCreateOptions(
|
||||||
|
string name = "",
|
||||||
|
bool allowMultiSpawn = false,
|
||||||
|
float autoReleaseInterval = float.MaxValue,
|
||||||
|
int capacity = int.MaxValue,
|
||||||
|
float expireTime = float.MaxValue,
|
||||||
|
int priority = 0)
|
||||||
|
{
|
||||||
|
Name = name ?? string.Empty;
|
||||||
|
AllowMultiSpawn = allowMultiSpawn;
|
||||||
|
AutoReleaseInterval = autoReleaseInterval;
|
||||||
|
Capacity = capacity;
|
||||||
|
ExpireTime = expireTime;
|
||||||
|
Priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectPoolCreateOptions WithName(string name)
|
||||||
|
=> new ObjectPoolCreateOptions(name, AllowMultiSpawn, AutoReleaseInterval, Capacity, ExpireTime, Priority);
|
||||||
|
|
||||||
|
public static ObjectPoolCreateOptions Single(string name = "")
|
||||||
|
=> new ObjectPoolCreateOptions(name: name);
|
||||||
|
|
||||||
|
public static ObjectPoolCreateOptions Multi(string name = "")
|
||||||
|
=> new ObjectPoolCreateOptions(name: name, allowMultiSpawn: true);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 对象池管理器。
|
/// 对象池管理器。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IObjectPoolService : IService, IServiceTickable
|
public interface IObjectPoolService : IService, IServiceTickable
|
||||||
{
|
{
|
||||||
/// <summary>
|
int Count { get; }
|
||||||
/// 获取对象池数量。
|
|
||||||
/// </summary>
|
|
||||||
int Count
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查是否存在对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <returns>是否存在对象池。</returns>
|
|
||||||
bool HasObjectPool<T>() where T : ObjectBase;
|
bool HasObjectPool<T>() where T : ObjectBase;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查是否存在对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <returns>是否存在对象池。</returns>
|
|
||||||
bool HasObjectPool(Type objectType);
|
bool HasObjectPool(Type objectType);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查是否存在对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <returns>是否存在对象池。</returns>
|
|
||||||
bool HasObjectPool<T>(string name) where T : ObjectBase;
|
bool HasObjectPool<T>(string name) where T : ObjectBase;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查是否存在对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <returns>是否存在对象池。</returns>
|
|
||||||
bool HasObjectPool(Type objectType, string name);
|
bool HasObjectPool(Type objectType, string name);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查是否存在对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="condition">要检查的条件。</param>
|
|
||||||
/// <returns>是否存在对象池。</returns>
|
|
||||||
bool HasObjectPool(Predicate<ObjectPoolBase> condition);
|
bool HasObjectPool(Predicate<ObjectPoolBase> condition);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <returns>要获取的对象池。</returns>
|
|
||||||
IObjectPool<T> GetObjectPool<T>() where T : ObjectBase;
|
IObjectPool<T> GetObjectPool<T>() where T : ObjectBase;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <returns>要获取的对象池。</returns>
|
|
||||||
ObjectPoolBase GetObjectPool(Type objectType);
|
ObjectPoolBase GetObjectPool(Type objectType);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <returns>要获取的对象池。</returns>
|
|
||||||
IObjectPool<T> GetObjectPool<T>(string name) where T : ObjectBase;
|
IObjectPool<T> GetObjectPool<T>(string name) where T : ObjectBase;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <returns>要获取的对象池。</returns>
|
|
||||||
ObjectPoolBase GetObjectPool(Type objectType, string name);
|
ObjectPoolBase GetObjectPool(Type objectType, string name);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="condition">要检查的条件。</param>
|
|
||||||
/// <returns>要获取的对象池。</returns>
|
|
||||||
ObjectPoolBase GetObjectPool(Predicate<ObjectPoolBase> condition);
|
ObjectPoolBase GetObjectPool(Predicate<ObjectPoolBase> condition);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="condition">要检查的条件。</param>
|
|
||||||
/// <returns>要获取的对象池。</returns>
|
|
||||||
ObjectPoolBase[] GetObjectPools(Predicate<ObjectPoolBase> condition);
|
ObjectPoolBase[] GetObjectPools(Predicate<ObjectPoolBase> condition);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="condition">要检查的条件。</param>
|
|
||||||
/// <param name="results">要获取的对象池。</param>
|
|
||||||
void GetObjectPools(Predicate<ObjectPoolBase> condition, List<ObjectPoolBase> results);
|
void GetObjectPools(Predicate<ObjectPoolBase> condition, List<ObjectPoolBase> results);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>所有对象池。</returns>
|
|
||||||
ObjectPoolBase[] GetAllObjectPools();
|
ObjectPoolBase[] GetAllObjectPools();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="results">所有对象池。</param>
|
|
||||||
void GetAllObjectPools(List<ObjectPoolBase> results);
|
void GetAllObjectPools(List<ObjectPoolBase> results);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sort">是否根据对象池的优先级排序。</param>
|
|
||||||
/// <returns>所有对象池。</returns>
|
|
||||||
ObjectPoolBase[] GetAllObjectPools(bool sort);
|
ObjectPoolBase[] GetAllObjectPools(bool sort);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sort">是否根据对象池的优先级排序。</param>
|
|
||||||
/// <param name="results">所有对象池。</param>
|
|
||||||
void GetAllObjectPools(bool sort, List<ObjectPoolBase> results);
|
void GetAllObjectPools(bool sort, List<ObjectPoolBase> results);
|
||||||
|
|
||||||
/// <summary>
|
IObjectPool<T> CreatePool<T>(ObjectPoolCreateOptions options = default) where T : ObjectBase;
|
||||||
/// 创建允许单次获取的对象池。
|
ObjectPoolBase CreatePool(Type objectType, ObjectPoolCreateOptions options = default);
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>() where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(float expireTime) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float expireTime) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, float expireTime) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, float expireTime) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许单次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>() where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(float expireTime) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float expireTime) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, float expireTime) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, float expireTime) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建允许多次获取的对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">对象池名称。</param>
|
|
||||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
|
||||||
/// <param name="capacity">对象池的容量。</param>
|
|
||||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
|
||||||
/// <param name="priority">对象池的优先级。</param>
|
|
||||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
|
||||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <returns>是否销毁对象池成功。</returns>
|
|
||||||
bool DestroyObjectPool<T>() where T : ObjectBase;
|
bool DestroyObjectPool<T>() where T : ObjectBase;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <returns>是否销毁对象池成功。</returns>
|
|
||||||
bool DestroyObjectPool(Type objectType);
|
bool DestroyObjectPool(Type objectType);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="name">要销毁的对象池名称。</param>
|
|
||||||
/// <returns>是否销毁对象池成功。</returns>
|
|
||||||
bool DestroyObjectPool<T>(string name) where T : ObjectBase;
|
bool DestroyObjectPool<T>(string name) where T : ObjectBase;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectType">对象类型。</param>
|
|
||||||
/// <param name="name">要销毁的对象池名称。</param>
|
|
||||||
/// <returns>是否销毁对象池成功。</returns>
|
|
||||||
bool DestroyObjectPool(Type objectType, string name);
|
bool DestroyObjectPool(Type objectType, string name);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">对象类型。</typeparam>
|
|
||||||
/// <param name="objectPool">要销毁的对象池。</param>
|
|
||||||
/// <returns>是否销毁对象池成功。</returns>
|
|
||||||
bool DestroyObjectPool<T>(IObjectPool<T> objectPool) where T : ObjectBase;
|
bool DestroyObjectPool<T>(IObjectPool<T> objectPool) where T : ObjectBase;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 销毁对象池。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="objectPool">要销毁的对象池。</param>
|
|
||||||
/// <returns>是否销毁对象池成功。</returns>
|
|
||||||
bool DestroyObjectPool(ObjectPoolBase objectPool);
|
bool DestroyObjectPool(ObjectPoolBase objectPool);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 释放对象池中的可释放对象。
|
|
||||||
/// </summary>
|
|
||||||
void Release();
|
void Release();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 释放对象池中的所有未使用对象。
|
|
||||||
/// </summary>
|
|
||||||
void ReleaseAllUnused();
|
void ReleaseAllUnused();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
using AlicizaX.ObjectPool;
|
using AlicizaX.ObjectPool;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX
|
namespace AlicizaX
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 对象池组件。
|
/// 对象池组件。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ObjectPoolComponent : MonoBehaviour
|
public sealed class ObjectPoolComponent : MonoBehaviour
|
||||||
{
|
{
|
||||||
private IObjectPoolService _mObjectPoolService = null;
|
private IObjectPoolService _mObjectPoolService = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取对象池数量。
|
/// 获取对象池数量。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
@ -20,7 +20,7 @@ namespace AlicizaX
|
|||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_mObjectPoolService = AppServices.GetOrCreateScope<AppScope>().Register(new ObjectPoolService());
|
_mObjectPoolService = AppServices.App.Register(new ObjectPoolService());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
@ -29,13 +29,14 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取所有对象池。
|
/// 获取所有对象池。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sort">是否根据对象池的优先级排序。</param>
|
/// <param name="sort">是否根据对象池的优先级排序。</param>
|
||||||
/// <returns>所有对象池。</returns>
|
/// <returns>所有对象池。</returns>
|
||||||
public ObjectPoolBase[] GetAllObjectPools(bool sort)
|
public ObjectPoolBase[] GetAllObjectPools(bool sort)
|
||||||
{
|
{
|
||||||
return _mObjectPoolService.GetAllObjectPools(sort);
|
return _mObjectPoolService.GetAllObjectPools(sort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -354,6 +354,29 @@ namespace AlicizaX.ObjectPool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IObjectPool<T> CreatePool<T>(ObjectPoolCreateOptions options = default) where T : ObjectBase
|
||||||
|
{
|
||||||
|
return InternalCreateObjectPool<T>(
|
||||||
|
options.Name,
|
||||||
|
options.AllowMultiSpawn,
|
||||||
|
NormalizeAutoReleaseInterval(options.AutoReleaseInterval),
|
||||||
|
NormalizeCapacity(options.Capacity),
|
||||||
|
NormalizeExpireTime(options.ExpireTime),
|
||||||
|
options.Priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectPoolBase CreatePool(Type objectType, ObjectPoolCreateOptions options = default)
|
||||||
|
{
|
||||||
|
return InternalCreateObjectPool(
|
||||||
|
objectType,
|
||||||
|
options.Name,
|
||||||
|
options.AllowMultiSpawn,
|
||||||
|
NormalizeAutoReleaseInterval(options.AutoReleaseInterval),
|
||||||
|
NormalizeCapacity(options.Capacity),
|
||||||
|
NormalizeExpireTime(options.ExpireTime),
|
||||||
|
options.Priority);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建允许单次获取的对象池。
|
/// 创建允许单次获取的对象池。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1212,6 +1235,21 @@ namespace AlicizaX.ObjectPool
|
|||||||
return m_ObjectPools.ContainsKey(typeNamePair);
|
return m_ObjectPools.ContainsKey(typeNamePair);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float NormalizeAutoReleaseInterval(float autoReleaseInterval)
|
||||||
|
{
|
||||||
|
return autoReleaseInterval == default ? DefaultExpireTime : autoReleaseInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int NormalizeCapacity(int capacity)
|
||||||
|
{
|
||||||
|
return capacity == default ? DefaultCapacity : capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float NormalizeExpireTime(float expireTime)
|
||||||
|
{
|
||||||
|
return expireTime == default ? DefaultExpireTime : expireTime;
|
||||||
|
}
|
||||||
|
|
||||||
private ObjectPoolBase InternalGetObjectPool(TypeNamePair typeNamePair)
|
private ObjectPoolBase InternalGetObjectPool(TypeNamePair typeNamePair)
|
||||||
{
|
{
|
||||||
ObjectPoolBase objectPool = null;
|
ObjectPoolBase objectPool = null;
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
using UnityEngine.Internal;
|
using UnityEngine.Internal;
|
||||||
@ -17,6 +16,7 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
private static GameObject _entity;
|
private static GameObject _entity;
|
||||||
private static MainBehaviour _behaviour;
|
private static MainBehaviour _behaviour;
|
||||||
|
private static UtilityLoopService _loopService;
|
||||||
|
|
||||||
#region 控制协程Coroutine
|
#region 控制协程Coroutine
|
||||||
|
|
||||||
@ -103,13 +103,7 @@ namespace AlicizaX
|
|||||||
/// <param name="fun"></param>
|
/// <param name="fun"></param>
|
||||||
public static void AddUpdateListener(UnityAction fun)
|
public static void AddUpdateListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
AddUpdateListenerImp(fun).Forget();
|
EnsureLoopService().AddUpdateListener(fun);
|
||||||
}
|
|
||||||
|
|
||||||
private static async UniTaskVoid AddUpdateListenerImp(UnityAction fun)
|
|
||||||
{
|
|
||||||
await UniTask.Yield(PlayerLoopTiming.LastPreUpdate);
|
|
||||||
_behaviour.AddUpdateListener(fun);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -118,13 +112,7 @@ namespace AlicizaX
|
|||||||
/// <param name="fun"></param>
|
/// <param name="fun"></param>
|
||||||
public static void AddFixedUpdateListener(UnityAction fun)
|
public static void AddFixedUpdateListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
AddFixedUpdateListenerImp(fun).Forget();
|
EnsureLoopService().AddFixedUpdateListener(fun);
|
||||||
}
|
|
||||||
|
|
||||||
private static async UniTaskVoid AddFixedUpdateListenerImp(UnityAction fun)
|
|
||||||
{
|
|
||||||
await UniTask.Yield(PlayerLoopTiming.LastEarlyUpdate);
|
|
||||||
_behaviour.AddFixedUpdateListener(fun);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -133,13 +121,7 @@ namespace AlicizaX
|
|||||||
/// <param name="fun"></param>
|
/// <param name="fun"></param>
|
||||||
public static void AddLateUpdateListener(UnityAction fun)
|
public static void AddLateUpdateListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
AddLateUpdateListenerImp(fun).Forget();
|
EnsureLoopService().AddLateUpdateListener(fun);
|
||||||
}
|
|
||||||
|
|
||||||
private static async UniTaskVoid AddLateUpdateListenerImp(UnityAction fun)
|
|
||||||
{
|
|
||||||
await UniTask.Yield(PlayerLoopTiming.LastPreLateUpdate);
|
|
||||||
_behaviour.AddLateUpdateListener(fun);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -148,7 +130,7 @@ namespace AlicizaX
|
|||||||
/// <param name="fun"></param>
|
/// <param name="fun"></param>
|
||||||
public static void RemoveUpdateListener(UnityAction fun)
|
public static void RemoveUpdateListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
_behaviour.RemoveUpdateListener(fun);
|
_loopService?.RemoveUpdateListener(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -157,7 +139,7 @@ namespace AlicizaX
|
|||||||
/// <param name="fun"></param>
|
/// <param name="fun"></param>
|
||||||
public static void RemoveFixedUpdateListener(UnityAction fun)
|
public static void RemoveFixedUpdateListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
_behaviour.RemoveFixedUpdateListener(fun);
|
_loopService?.RemoveFixedUpdateListener(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -166,7 +148,7 @@ namespace AlicizaX
|
|||||||
/// <param name="fun"></param>
|
/// <param name="fun"></param>
|
||||||
public static void RemoveLateUpdateListener(UnityAction fun)
|
public static void RemoveLateUpdateListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
_behaviour.RemoveLateUpdateListener(fun);
|
_loopService?.RemoveLateUpdateListener(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -196,7 +178,7 @@ namespace AlicizaX
|
|||||||
/// <param name="fun"></param>
|
/// <param name="fun"></param>
|
||||||
public static void AddOnDrawGizmosListener(UnityAction fun)
|
public static void AddOnDrawGizmosListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
_behaviour.AddOnDrawGizmosListener(fun);
|
EnsureLoopService().AddOnDrawGizmosListener(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -205,7 +187,7 @@ namespace AlicizaX
|
|||||||
/// <param name="fun"></param>
|
/// <param name="fun"></param>
|
||||||
public static void RemoveOnDrawGizmosListener(UnityAction fun)
|
public static void RemoveOnDrawGizmosListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
_behaviour.RemoveOnDrawGizmosListener(fun);
|
_loopService?.RemoveOnDrawGizmosListener(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -256,6 +238,7 @@ namespace AlicizaX
|
|||||||
_entity.SetActive(true);
|
_entity.SetActive(true);
|
||||||
_entity.transform.SetParent(parent);
|
_entity.transform.SetParent(parent);
|
||||||
_behaviour = _entity.AddComponent<MainBehaviour>();
|
_behaviour = _entity.AddComponent<MainBehaviour>();
|
||||||
|
RegisterLoopServiceIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -270,6 +253,12 @@ namespace AlicizaX
|
|||||||
_behaviour.Shutdown();
|
_behaviour.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_loopService != null)
|
||||||
|
{
|
||||||
|
_loopService.Clear();
|
||||||
|
_loopService = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (_entity != null)
|
if (_entity != null)
|
||||||
{
|
{
|
||||||
UnityEngine.Object.Destroy(_entity);
|
UnityEngine.Object.Destroy(_entity);
|
||||||
@ -279,40 +268,44 @@ namespace AlicizaX
|
|||||||
_entity = null;
|
_entity = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void RegisterLoopServiceIfNeeded()
|
||||||
|
{
|
||||||
|
if (_loopService != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AppServices.HasWorld)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AppServices.TryGet(out UtilityLoopService service))
|
||||||
|
{
|
||||||
|
_loopService = service;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_loopService = AppServices.App.Register(new UtilityLoopService());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UtilityLoopService EnsureLoopService()
|
||||||
|
{
|
||||||
|
RegisterLoopServiceIfNeeded();
|
||||||
|
if (_loopService == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Utility loop service is not available.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _loopService;
|
||||||
|
}
|
||||||
|
|
||||||
private class MainBehaviour : MonoBehaviour
|
private class MainBehaviour : MonoBehaviour
|
||||||
{
|
{
|
||||||
private event UnityAction UpdateEvent;
|
|
||||||
private event UnityAction FixedUpdateEvent;
|
|
||||||
private event UnityAction LateUpdateEvent;
|
|
||||||
private event UnityAction DestroyEvent;
|
private event UnityAction DestroyEvent;
|
||||||
private event UnityAction OnDrawGizmosEvent;
|
|
||||||
private event UnityAction<bool> OnApplicationPauseEvent;
|
private event UnityAction<bool> OnApplicationPauseEvent;
|
||||||
private event UnityAction OnApplicationQuitEvent;
|
private event UnityAction OnApplicationQuitEvent;
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
if (UpdateEvent != null)
|
|
||||||
{
|
|
||||||
UpdateEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FixedUpdate()
|
|
||||||
{
|
|
||||||
if (FixedUpdateEvent != null)
|
|
||||||
{
|
|
||||||
FixedUpdateEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LateUpdate()
|
|
||||||
{
|
|
||||||
if (LateUpdateEvent != null)
|
|
||||||
{
|
|
||||||
LateUpdateEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
if (DestroyEvent != null)
|
if (DestroyEvent != null)
|
||||||
@ -321,14 +314,6 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDrawGizmos()
|
|
||||||
{
|
|
||||||
if (OnDrawGizmosEvent != null)
|
|
||||||
{
|
|
||||||
OnDrawGizmosEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnApplicationPause(bool pauseStatus)
|
private void OnApplicationPause(bool pauseStatus)
|
||||||
{
|
{
|
||||||
if (OnApplicationPauseEvent != null)
|
if (OnApplicationPauseEvent != null)
|
||||||
@ -345,36 +330,6 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddLateUpdateListener(UnityAction fun)
|
|
||||||
{
|
|
||||||
LateUpdateEvent += fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveLateUpdateListener(UnityAction fun)
|
|
||||||
{
|
|
||||||
LateUpdateEvent -= fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddFixedUpdateListener(UnityAction fun)
|
|
||||||
{
|
|
||||||
FixedUpdateEvent += fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveFixedUpdateListener(UnityAction fun)
|
|
||||||
{
|
|
||||||
FixedUpdateEvent -= fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddUpdateListener(UnityAction fun)
|
|
||||||
{
|
|
||||||
UpdateEvent += fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveUpdateListener(UnityAction fun)
|
|
||||||
{
|
|
||||||
UpdateEvent -= fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddDestroyListener(UnityAction fun)
|
public void AddDestroyListener(UnityAction fun)
|
||||||
{
|
{
|
||||||
DestroyEvent += fun;
|
DestroyEvent += fun;
|
||||||
@ -385,16 +340,6 @@ namespace AlicizaX
|
|||||||
DestroyEvent -= fun;
|
DestroyEvent -= fun;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddOnDrawGizmosListener(UnityAction fun)
|
|
||||||
{
|
|
||||||
OnDrawGizmosEvent += fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveOnDrawGizmosListener(UnityAction fun)
|
|
||||||
{
|
|
||||||
OnDrawGizmosEvent -= fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddOnApplicationPauseListener(UnityAction<bool> fun)
|
public void AddOnApplicationPauseListener(UnityAction<bool> fun)
|
||||||
{
|
{
|
||||||
OnApplicationPauseEvent += fun;
|
OnApplicationPauseEvent += fun;
|
||||||
@ -418,10 +363,6 @@ namespace AlicizaX
|
|||||||
|
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
UpdateEvent = null;
|
|
||||||
FixedUpdateEvent = null;
|
|
||||||
LateUpdateEvent = null;
|
|
||||||
OnDrawGizmosEvent = null;
|
|
||||||
DestroyEvent = null;
|
DestroyEvent = null;
|
||||||
OnApplicationPauseEvent = null;
|
OnApplicationPauseEvent = null;
|
||||||
OnApplicationQuitEvent = null;
|
OnApplicationQuitEvent = null;
|
||||||
@ -439,6 +380,91 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed class UtilityLoopService : ServiceBase, IServiceTickable, IServiceLateTickable, IServiceFixedTickable, IServiceGizmoDrawable
|
||||||
|
{
|
||||||
|
private event UnityAction UpdateEvent;
|
||||||
|
private event UnityAction FixedUpdateEvent;
|
||||||
|
private event UnityAction LateUpdateEvent;
|
||||||
|
private event UnityAction OnDrawGizmosEvent;
|
||||||
|
|
||||||
|
protected override void OnInitialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDestroyService()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IServiceTickable.Tick(float deltaTime)
|
||||||
|
{
|
||||||
|
UpdateEvent?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IServiceLateTickable.LateTick(float deltaTime)
|
||||||
|
{
|
||||||
|
LateUpdateEvent?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IServiceFixedTickable.FixedTick(float fixedDeltaTime)
|
||||||
|
{
|
||||||
|
FixedUpdateEvent?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IServiceGizmoDrawable.DrawGizmos()
|
||||||
|
{
|
||||||
|
OnDrawGizmosEvent?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
UpdateEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
UpdateEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddFixedUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
FixedUpdateEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveFixedUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
FixedUpdateEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLateUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
LateUpdateEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveLateUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
LateUpdateEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOnDrawGizmosListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
OnDrawGizmosEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveOnDrawGizmosListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
OnDrawGizmosEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
UpdateEvent = null;
|
||||||
|
FixedUpdateEvent = null;
|
||||||
|
LateUpdateEvent = null;
|
||||||
|
OnDrawGizmosEvent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
using AlicizaX;
|
using AlicizaX;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Audio;
|
using UnityEngine.Audio;
|
||||||
|
|
||||||
namespace AlicizaX.Audio.Runtime
|
namespace AlicizaX.Audio.Runtime
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 音效管理,为游戏提供统一的音效播放接口。
|
/// 音效管理,为游戏提供统一的音效播放接口。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>场景3D音效挂到场景物件、技能3D音效挂到技能特效上,并在AudioSource的Output上设置对应分类的AudioMixerGroup</remarks>
|
/// <remarks>场景3D音效挂到场景物件、技能3D音效挂到技能特效上,并在AudioSource的Output上设置对应分类的AudioMixerGroup</remarks>
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
[AddComponentMenu("Game Framework/Audio")]
|
[AddComponentMenu("Game Framework/Audio")]
|
||||||
public sealed class AudioComponent : MonoBehaviour
|
public sealed class AudioComponent : MonoBehaviour
|
||||||
@ -22,11 +22,11 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_audioService = AppServices.GetOrCreateScope<AppScope>().Register(new AudioService());
|
_audioService = AppServices.App.Register(new AudioService());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化音频模块。
|
/// 初始化音频模块。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
@ -46,3 +46,4 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ using Object = UnityEngine.Object;
|
|||||||
namespace AlicizaX.Debugger.Runtime
|
namespace AlicizaX.Debugger.Runtime
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 调试器组件。
|
/// 靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD>隞嗚<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
[AddComponentMenu("Game Framework/Debugger")]
|
[AddComponentMenu("Game Framework/Debugger")]
|
||||||
@ -28,17 +28,17 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认调试器漂浮框大小。
|
/// 暺䁅恕靚<EFBFBD><EFBFBD><EFBFBD>冽<EFBFBD>瘚格<EFBFBD>憭批<EFBFBD><EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static readonly Rect DefaultIconRect = new Rect(10f, 10f, 60f, 60f);
|
internal static readonly Rect DefaultIconRect = new Rect(10f, 10f, 60f, 60f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认调试器窗口大小。
|
/// 暺䁅恕靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD>之撠譌<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static readonly Rect DefaultWindowRect = new Rect(10f, 10f, 640f, 480f);
|
internal static readonly Rect DefaultWindowRect = new Rect(10f, 10f, 640f, 480f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认调试器窗口缩放比例。
|
/// 暺䁅恕靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD>憬<EFBFBD>暹<EFBFBD>靘卝<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static readonly float DefaultWindowScale = 1f;
|
internal static readonly float DefaultWindowScale = 1f;
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
private FpsCounter m_FpsCounter = null;
|
private FpsCounter m_FpsCounter = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置调试器窗口是否激活。
|
/// <EFBFBD>瑕<EFBFBD><EFBFBD>𤥁挽蝵株<EFBFBD>霂訫膥蝒堒藁<EFBFBD>臬炏瞈<EFBFBD>瘣颯<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ActiveWindow
|
public bool ActiveWindow
|
||||||
{
|
{
|
||||||
@ -108,7 +108,7 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置是否显示完整调试器界面。
|
/// <EFBFBD>瑕<EFBFBD><EFBFBD>𤥁挽蝵格糓<EFBFBD>行遬蝷箏<EFBFBD><EFBFBD>渲<EFBFBD>霂訫膥<EFBFBD>屸𢒰<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowFullWindow
|
public bool ShowFullWindow
|
||||||
{
|
{
|
||||||
@ -117,7 +117,7 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置调试器漂浮框大小。
|
/// <EFBFBD>瑕<EFBFBD><EFBFBD>𤥁挽蝵株<EFBFBD>霂訫膥瞍<EFBFBD>筑獢<EFBFBD>之撠譌<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Rect IconRect
|
public Rect IconRect
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置调试器窗口大小。
|
/// <EFBFBD>瑕<EFBFBD><EFBFBD>𤥁挽蝵株<EFBFBD>霂訫膥蝒堒藁憭批<EFBFBD><EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Rect WindowRect
|
public Rect WindowRect
|
||||||
{
|
{
|
||||||
@ -135,7 +135,7 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置调试器窗口缩放比例。
|
/// <EFBFBD>瑕<EFBFBD><EFBFBD>𤥁挽蝵株<EFBFBD>霂訫膥蝒堒藁蝻拇𦆮瘥𥪯<EFBFBD><EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float WindowScale
|
public float WindowScale
|
||||||
{
|
{
|
||||||
@ -144,12 +144,12 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 游戏框架组件初始化。
|
/// 皜豢<EFBFBD>獢<EFBFBD>沲蝏<EFBFBD>辣<EFBFBD>嘥<EFBFBD><EFBFBD>硔<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_instance = this;
|
_instance = this;
|
||||||
_mDebuggerService = AppServices.GetOrCreateScope<AppScope>().Register(new DebuggerService());
|
_mDebuggerService = AppServices.App.Register(new DebuggerService());
|
||||||
if (_mDebuggerService == null)
|
if (_mDebuggerService == null)
|
||||||
{
|
{
|
||||||
Log.Error("Debugger manager is invalid.");
|
Log.Error("Debugger manager is invalid.");
|
||||||
@ -256,48 +256,48 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册调试器窗口。
|
/// 瘜典<EFBFBD>靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">调试器窗口路径。</param>
|
/// <param name="path">靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param>
|
||||||
/// <param name="debuggerWindow">要注册的调试器窗口。</param>
|
/// <param name="debuggerWindow">閬<EFBFBD>釣<EFBFBD>𣬚<EFBFBD>靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/param>
|
||||||
/// <param name="args">初始化调试器窗口参数。</param>
|
/// <param name="args"><EFBFBD>嘥<EFBFBD><EFBFBD>𤥁<EFBFBD>霂訫膥蝒堒藁<EFBFBD><EFBFBD>㺭<EFBFBD>?/param>
|
||||||
public void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow, params object[] args)
|
public void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow, params object[] args)
|
||||||
{
|
{
|
||||||
_mDebuggerService.RegisterDebuggerWindow(path, debuggerWindow, args);
|
_mDebuggerService.RegisterDebuggerWindow(path, debuggerWindow, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解除注册调试器窗口。
|
/// 閫<EFBFBD>膄瘜典<EFBFBD>靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">调试器窗口路径。</param>
|
/// <param name="path">靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param>
|
||||||
/// <returns>是否解除注册调试器窗口成功。</returns>
|
/// <returns><EFBFBD>臬炏閫<EFBFBD>膄瘜典<EFBFBD>靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>麄<EFBFBD>?/returns>
|
||||||
public bool UnregisterDebuggerWindow(string path)
|
public bool UnregisterDebuggerWindow(string path)
|
||||||
{
|
{
|
||||||
return _mDebuggerService.UnregisterDebuggerWindow(path);
|
return _mDebuggerService.UnregisterDebuggerWindow(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取调试器窗口。
|
/// <EFBFBD>瑕<EFBFBD>靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">调试器窗口路径。</param>
|
/// <param name="path">靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param>
|
||||||
/// <returns>要获取的调试器窗口。</returns>
|
/// <returns>閬<EFBFBD>繮<EFBFBD>𣇉<EFBFBD>靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/returns>
|
||||||
public IDebuggerWindow GetDebuggerWindow(string path)
|
public IDebuggerWindow GetDebuggerWindow(string path)
|
||||||
{
|
{
|
||||||
return _mDebuggerService.GetDebuggerWindow(path);
|
return _mDebuggerService.GetDebuggerWindow(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 选中调试器窗口。
|
/// <EFBFBD>劐葉靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">调试器窗口路径。</param>
|
/// <param name="path">靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param>
|
||||||
/// <returns>是否成功选中调试器窗口。</returns>
|
/// <returns><EFBFBD>臬炏<EFBFBD>𣂼<EFBFBD><EFBFBD>劐葉靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/returns>
|
||||||
public bool SelectDebuggerWindow(string path)
|
public bool SelectDebuggerWindow(string path)
|
||||||
{
|
{
|
||||||
return _mDebuggerService.SelectDebuggerWindow(path);
|
return _mDebuggerService.SelectDebuggerWindow(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 还原调试器窗口布局。
|
/// 餈睃<EFBFBD>靚<EFBFBD><EFBFBD><EFBFBD>函<EFBFBD><EFBFBD><EFBFBD><EFBFBD>撅<EFBFBD><EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ResetLayout()
|
public void ResetLayout()
|
||||||
{
|
{
|
||||||
@ -307,19 +307,19 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取记录的所有日志。
|
/// <EFBFBD>瑕<EFBFBD>霈啣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㗇𠯫敹𨰜<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="results">要获取的日志。</param>
|
/// <param name="results">閬<EFBFBD>繮<EFBFBD>𣇉<EFBFBD><EFBFBD>亙<EFBFBD><EFBFBD>?/param>
|
||||||
public void GetRecentLogs(List<LogNode> results)
|
public void GetRecentLogs(List<LogNode> results)
|
||||||
{
|
{
|
||||||
m_ConsoleWindow.GetRecentLogs(results);
|
m_ConsoleWindow.GetRecentLogs(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取记录的最近日志。
|
/// <EFBFBD>瑕<EFBFBD>霈啣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>餈烐𠯫敹𨰜<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="results">要获取的日志。</param>
|
/// <param name="results">閬<EFBFBD>繮<EFBFBD>𣇉<EFBFBD><EFBFBD>亙<EFBFBD><EFBFBD>?/param>
|
||||||
/// <param name="count">要获取最近日志的数量。</param>
|
/// <param name="count">閬<EFBFBD>繮<EFBFBD>𡝗<EFBFBD>餈烐𠯫敹㛖<EFBFBD><EFBFBD>圈<EFBFBD><EFBFBD>?/param>
|
||||||
public void GetRecentLogs(List<LogNode> results, int count)
|
public void GetRecentLogs(List<LogNode> results, int count)
|
||||||
{
|
{
|
||||||
m_ConsoleWindow.GetRecentLogs(results, count);
|
m_ConsoleWindow.GetRecentLogs(results, count);
|
||||||
@ -417,3 +417,4 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,36 +1,152 @@
|
|||||||
using UnityEngine;
|
using System.Collections.Generic;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using AlicizaX.Resource.Runtime;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX.Localization.Runtime
|
namespace AlicizaX.Localization.Runtime
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本地化组件。
|
/// ±¾µØ»¯×é¼þ¡£
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
[AddComponentMenu("Game Framework/Localization")]
|
[AddComponentMenu("Game Framework/Localization")]
|
||||||
public sealed class LocalizationComponent : MonoBehaviour
|
public sealed class LocalizationComponent : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
private const string DefaultLanguage = "ChineseSimplified";
|
||||||
|
private const string RuntimeLanguagePrefsKey = "AlicizaX.Localization.Language";
|
||||||
|
|
||||||
private ILocalizationService _mLocalizationService = null;
|
private ILocalizationService _mLocalizationService = null;
|
||||||
|
|
||||||
public static string PrefsKey = Application.dataPath.GetHashCode() + "Language";
|
public static string PrefsKey = Application.dataPath.GetHashCode() + "Language";
|
||||||
|
|
||||||
[SerializeField] private string _language;
|
[SerializeField] private string _language;
|
||||||
|
[SerializeField] private List<GameLocaizationTable> _startupTables = new();
|
||||||
|
[SerializeField] private List<string> _startupTableLocations = new();
|
||||||
|
[SerializeField] private string _resourcePackageName = string.Empty;
|
||||||
|
|
||||||
internal void SetLanguage(string language)
|
internal void SetLanguage(string language)
|
||||||
{
|
{
|
||||||
_language = language;
|
_language = language;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
internal static void SaveLanguagePreference(string language)
|
||||||
{
|
{
|
||||||
_mLocalizationService = AppServices.GetOrCreateScope<AppScope>().Register(new LocalizationService());
|
if (string.IsNullOrEmpty(language))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
UnityEditor.EditorPrefs.SetString(PrefsKey, language);
|
||||||
|
#endif
|
||||||
|
PlayerPrefs.SetString(RuntimeLanguagePrefsKey, language);
|
||||||
|
PlayerPrefs.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string LoadLanguagePreference(string fallbackLanguage)
|
||||||
|
{
|
||||||
|
string fallback = string.IsNullOrEmpty(fallbackLanguage) ? DefaultLanguage : fallbackLanguage;
|
||||||
|
string language = PlayerPrefs.GetString(RuntimeLanguagePrefsKey, fallback);
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
language = UnityEditor.EditorPrefs.GetString(PrefsKey, language);
|
||||||
|
#endif
|
||||||
|
return string.IsNullOrEmpty(language) ? fallback : language;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (!AppServices.App.TryGet<ILocalizationService>(out _mLocalizationService))
|
||||||
|
{
|
||||||
|
_mLocalizationService = AppServices.App.Register(new LocalizationService());
|
||||||
|
}
|
||||||
|
|
||||||
if (_mLocalizationService == null)
|
if (_mLocalizationService == null)
|
||||||
{
|
{
|
||||||
Log.Info("Localization manager is invalid.");
|
Log.Info("Localization manager is invalid.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#if UNITY_EDITOR
|
|
||||||
_language = UnityEditor.EditorPrefs.GetString(LocalizationComponent.PrefsKey, "None");
|
_language = LoadLanguagePreference(_language);
|
||||||
#endif
|
|
||||||
_mLocalizationService.Initialize(_language);
|
_mLocalizationService.Initialize(_language);
|
||||||
|
ApplyStartupTables(_startupTables);
|
||||||
|
|
||||||
|
if (_startupTableLocations != null && _startupTableLocations.Count > 0)
|
||||||
|
{
|
||||||
|
LoadStartupTablesAsync().Forget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyStartupTables(List<GameLocaizationTable> tables)
|
||||||
|
{
|
||||||
|
if (tables == null || tables.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool applied = false;
|
||||||
|
for (int i = 0; i < tables.Count; i++)
|
||||||
|
{
|
||||||
|
GameLocaizationTable table = tables[i];
|
||||||
|
if (table == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!applied)
|
||||||
|
{
|
||||||
|
_mLocalizationService.CoverAddLocalizationConfig(table);
|
||||||
|
applied = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mLocalizationService.IncreAddLocalizationConfig(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async UniTaskVoid LoadStartupTablesAsync()
|
||||||
|
{
|
||||||
|
if (!AppServices.TryGet<IResourceService>(out var resourceService))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GameLocaizationTable> loadedTables = new(_startupTableLocations.Count);
|
||||||
|
for (int i = 0; i < _startupTableLocations.Count; i++)
|
||||||
|
{
|
||||||
|
string location = _startupTableLocations[i];
|
||||||
|
if (string.IsNullOrEmpty(location))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameLocaizationTable table = await resourceService.LoadAssetAsync<GameLocaizationTable>(location, default, _resourcePackageName);
|
||||||
|
if (table != null)
|
||||||
|
{
|
||||||
|
loadedTables.Add(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadedTables.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_startupTables == null)
|
||||||
|
{
|
||||||
|
_startupTables = new List<GameLocaizationTable>(loadedTables.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < loadedTables.Count; i++)
|
||||||
|
{
|
||||||
|
GameLocaizationTable table = loadedTables[i];
|
||||||
|
if (_startupTables.Contains(table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_startupTables.Add(table);
|
||||||
|
_mLocalizationService.IncreAddLocalizationConfig(table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Serialization;
|
|
||||||
|
|
||||||
namespace AlicizaX.Localization
|
namespace AlicizaX.Localization
|
||||||
{
|
{
|
||||||
@ -45,9 +43,53 @@ namespace AlicizaX.Localization
|
|||||||
#endif
|
#endif
|
||||||
public List<LocalizationLanguage> Languages = new();
|
public List<LocalizationLanguage> Languages = new();
|
||||||
|
|
||||||
|
[NonSerialized] private Dictionary<string, LocalizationLanguage> _languageMap;
|
||||||
|
[NonSerialized] private int _languageMapVersion = -1;
|
||||||
|
|
||||||
internal LocalizationLanguage GetLanguage(string languageCode)
|
internal LocalizationLanguage GetLanguage(string languageCode)
|
||||||
{
|
{
|
||||||
return Languages.Find(t => t.LanguageName == languageCode);
|
if (string.IsNullOrEmpty(languageCode) || Languages == null || Languages.Count == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureLanguageMap();
|
||||||
|
_languageMap.TryGetValue(languageCode, out LocalizationLanguage language);
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InvalidateLanguageLookup()
|
||||||
|
{
|
||||||
|
_languageMapVersion = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnsureLanguageMap()
|
||||||
|
{
|
||||||
|
int count = Languages?.Count ?? 0;
|
||||||
|
if (_languageMap != null && _languageMapVersion == count)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_languageMap ??= new Dictionary<string, LocalizationLanguage>(count, StringComparer.Ordinal);
|
||||||
|
_languageMap.Clear();
|
||||||
|
|
||||||
|
if (Languages != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Languages.Count; i++)
|
||||||
|
{
|
||||||
|
LocalizationLanguage language = Languages[i];
|
||||||
|
if (language == null || string.IsNullOrEmpty(language.LanguageName))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_languageMap[language.LanguageName] = language;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_languageMapVersion = count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,437 +1,447 @@
|
|||||||
using System.Collections.Generic;
|
using System.Threading;
|
||||||
using AlicizaX;
|
using AlicizaX;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
|
||||||
namespace AlicizaX.Localization.Runtime
|
namespace AlicizaX.Localization.Runtime
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本地化管理器接口。
|
/// 本地化管理器接口。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ILocalizationService : IService
|
public interface ILocalizationService : IService
|
||||||
{
|
{
|
||||||
public string Language { get; }
|
public string Language { get; }
|
||||||
|
|
||||||
void Initialize(string language);
|
void Initialize(string language);
|
||||||
|
bool TryGetRawString(string key, out string value);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString(string key);
|
string GetString(string key);
|
||||||
|
|
||||||
void ChangedLanguage(string language);
|
void ChangedLanguage(string language);
|
||||||
|
UniTask SwitchLanguageAsync(string language, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">字典参数的类型。</typeparam>
|
/// <typeparam name="T">字典参数的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="args">字典参数列表。</param>
|
/// <param name="args">字典参数列表。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString(string key, params object[] args);
|
string GetString(string key, params object[] args);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">字典参数的类型。</typeparam>
|
/// <typeparam name="T">字典参数的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg">字典参数。</param>
|
/// <param name="arg">字典参数。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T>(string key, T arg);
|
string GetString<T>(string key, T arg);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2>(string key, T1 arg1, T2 arg2);
|
string GetString<T1, T2>(string key, T1 arg1, T2 arg2);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3>(string key, T1 arg1, T2 arg2, T3 arg3);
|
string GetString<T1, T2, T3>(string key, T1 arg1, T2 arg2, T3 arg3);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
string GetString<T1, T2, T3, T4>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
string GetString<T1, T2, T3, T4, T5>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
string GetString<T1, T2, T3, T4, T5, T6>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
string GetString<T1, T2, T3, T4, T5, T6, T7>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
string GetString<T1, T2, T3, T4, T5, T6, T7, T8>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <param name="arg9">字典参数 9。</param>
|
/// <param name="arg9">字典参数 9。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9);
|
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
||||||
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <param name="arg9">字典参数 9。</param>
|
/// <param name="arg9">字典参数 9。</param>
|
||||||
/// <param name="arg10">字典参数 10。</param>
|
/// <param name="arg10">字典参数 10。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10);
|
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
||||||
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
||||||
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <param name="arg9">字典参数 9。</param>
|
/// <param name="arg9">字典参数 9。</param>
|
||||||
/// <param name="arg10">字典参数 10。</param>
|
/// <param name="arg10">字典参数 10。</param>
|
||||||
/// <param name="arg11">字典参数 11。</param>
|
/// <param name="arg11">字典参数 11。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(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 GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(string key, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
||||||
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
||||||
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
||||||
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <param name="arg9">字典参数 9。</param>
|
/// <param name="arg9">字典参数 9。</param>
|
||||||
/// <param name="arg10">字典参数 10。</param>
|
/// <param name="arg10">字典参数 10。</param>
|
||||||
/// <param name="arg11">字典参数 11。</param>
|
/// <param name="arg11">字典参数 11。</param>
|
||||||
/// <param name="arg12">字典参数 12。</param>
|
/// <param name="arg12">字典参数 12。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(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 GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(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);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
||||||
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
||||||
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
||||||
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
||||||
/// <typeparam name="T13">字典参数 13 的类型。</typeparam>
|
/// <typeparam name="T13">字典参数 13 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <param name="arg9">字典参数 9。</param>
|
/// <param name="arg9">字典参数 9。</param>
|
||||||
/// <param name="arg10">字典参数 10。</param>
|
/// <param name="arg10">字典参数 10。</param>
|
||||||
/// <param name="arg11">字典参数 11。</param>
|
/// <param name="arg11">字典参数 11。</param>
|
||||||
/// <param name="arg12">字典参数 12。</param>
|
/// <param name="arg12">字典参数 12。</param>
|
||||||
/// <param name="arg13">字典参数 13。</param>
|
/// <param name="arg13">字典参数 13。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(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 GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(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);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
||||||
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
||||||
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
||||||
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
||||||
/// <typeparam name="T13">字典参数 13 的类型。</typeparam>
|
/// <typeparam name="T13">字典参数 13 的类型。</typeparam>
|
||||||
/// <typeparam name="T14">字典参数 14 的类型。</typeparam>
|
/// <typeparam name="T14">字典参数 14 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <param name="arg9">字典参数 9。</param>
|
/// <param name="arg9">字典参数 9。</param>
|
||||||
/// <param name="arg10">字典参数 10。</param>
|
/// <param name="arg10">字典参数 10。</param>
|
||||||
/// <param name="arg11">字典参数 11。</param>
|
/// <param name="arg11">字典参数 11。</param>
|
||||||
/// <param name="arg12">字典参数 12。</param>
|
/// <param name="arg12">字典参数 12。</param>
|
||||||
/// <param name="arg13">字典参数 13。</param>
|
/// <param name="arg13">字典参数 13。</param>
|
||||||
/// <param name="arg14">字典参数 14。</param>
|
/// <param name="arg14">字典参数 14。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(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 GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(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);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
||||||
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
||||||
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
||||||
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
||||||
/// <typeparam name="T13">字典参数 13 的类型。</typeparam>
|
/// <typeparam name="T13">字典参数 13 的类型。</typeparam>
|
||||||
/// <typeparam name="T14">字典参数 14 的类型。</typeparam>
|
/// <typeparam name="T14">字典参数 14 的类型。</typeparam>
|
||||||
/// <typeparam name="T15">字典参数 15 的类型。</typeparam>
|
/// <typeparam name="T15">字典参数 15 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <param name="arg9">字典参数 9。</param>
|
/// <param name="arg9">字典参数 9。</param>
|
||||||
/// <param name="arg10">字典参数 10。</param>
|
/// <param name="arg10">字典参数 10。</param>
|
||||||
/// <param name="arg11">字典参数 11。</param>
|
/// <param name="arg11">字典参数 11。</param>
|
||||||
/// <param name="arg12">字典参数 12。</param>
|
/// <param name="arg12">字典参数 12。</param>
|
||||||
/// <param name="arg13">字典参数 13。</param>
|
/// <param name="arg13">字典参数 13。</param>
|
||||||
/// <param name="arg14">字典参数 14。</param>
|
/// <param name="arg14">字典参数 14。</param>
|
||||||
/// <param name="arg15">字典参数 15。</param>
|
/// <param name="arg15">字典参数 15。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(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 GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(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);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典内容字符串。
|
/// 根据字典主键获取字典内容字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
/// <typeparam name="T1">字典参数 1 的类型。</typeparam>
|
||||||
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
/// <typeparam name="T2">字典参数 2 的类型。</typeparam>
|
||||||
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
/// <typeparam name="T3">字典参数 3 的类型。</typeparam>
|
||||||
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
/// <typeparam name="T4">字典参数 4 的类型。</typeparam>
|
||||||
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
/// <typeparam name="T5">字典参数 5 的类型。</typeparam>
|
||||||
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
/// <typeparam name="T6">字典参数 6 的类型。</typeparam>
|
||||||
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
/// <typeparam name="T7">字典参数 7 的类型。</typeparam>
|
||||||
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
/// <typeparam name="T8">字典参数 8 的类型。</typeparam>
|
||||||
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
/// <typeparam name="T9">字典参数 9 的类型。</typeparam>
|
||||||
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
/// <typeparam name="T10">字典参数 10 的类型。</typeparam>
|
||||||
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
/// <typeparam name="T11">字典参数 11 的类型。</typeparam>
|
||||||
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
/// <typeparam name="T12">字典参数 12 的类型。</typeparam>
|
||||||
/// <typeparam name="T13">字典参数 13 的类型。</typeparam>
|
/// <typeparam name="T13">字典参数 13 的类型。</typeparam>
|
||||||
/// <typeparam name="T14">字典参数 14 的类型。</typeparam>
|
/// <typeparam name="T14">字典参数 14 的类型。</typeparam>
|
||||||
/// <typeparam name="T15">字典参数 15 的类型。</typeparam>
|
/// <typeparam name="T15">字典参数 15 的类型。</typeparam>
|
||||||
/// <typeparam name="T16">字典参数 16 的类型。</typeparam>
|
/// <typeparam name="T16">字典参数 16 的类型。</typeparam>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <param name="arg1">字典参数 1。</param>
|
/// <param name="arg1">字典参数 1。</param>
|
||||||
/// <param name="arg2">字典参数 2。</param>
|
/// <param name="arg2">字典参数 2。</param>
|
||||||
/// <param name="arg3">字典参数 3。</param>
|
/// <param name="arg3">字典参数 3。</param>
|
||||||
/// <param name="arg4">字典参数 4。</param>
|
/// <param name="arg4">字典参数 4。</param>
|
||||||
/// <param name="arg5">字典参数 5。</param>
|
/// <param name="arg5">字典参数 5。</param>
|
||||||
/// <param name="arg6">字典参数 6。</param>
|
/// <param name="arg6">字典参数 6。</param>
|
||||||
/// <param name="arg7">字典参数 7。</param>
|
/// <param name="arg7">字典参数 7。</param>
|
||||||
/// <param name="arg8">字典参数 8。</param>
|
/// <param name="arg8">字典参数 8。</param>
|
||||||
/// <param name="arg9">字典参数 9。</param>
|
/// <param name="arg9">字典参数 9。</param>
|
||||||
/// <param name="arg10">字典参数 10。</param>
|
/// <param name="arg10">字典参数 10。</param>
|
||||||
/// <param name="arg11">字典参数 11。</param>
|
/// <param name="arg11">字典参数 11。</param>
|
||||||
/// <param name="arg12">字典参数 12。</param>
|
/// <param name="arg12">字典参数 12。</param>
|
||||||
/// <param name="arg13">字典参数 13。</param>
|
/// <param name="arg13">字典参数 13。</param>
|
||||||
/// <param name="arg14">字典参数 14。</param>
|
/// <param name="arg14">字典参数 14。</param>
|
||||||
/// <param name="arg15">字典参数 15。</param>
|
/// <param name="arg15">字典参数 15。</param>
|
||||||
/// <param name="arg16">字典参数 16。</param>
|
/// <param name="arg16">字典参数 16。</param>
|
||||||
/// <returns>要获取的字典内容字符串。</returns>
|
/// <returns>要获取的字典内容字符串。</returns>
|
||||||
string GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(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 GetString<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(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);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据字典主键获取字典值。
|
/// 根据字典主键获取字典值。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">字典主键。</param>
|
/// <param name="key">字典主键。</param>
|
||||||
/// <returns>字典值。</returns>
|
/// <returns>字典值。</returns>
|
||||||
string GetRawString(string key);
|
string GetRawString(string key);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 增量增加多语言配置
|
/// 增量增加多语言配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="table"></param>
|
/// <param name="table"></param>
|
||||||
void IncreAddLocalizationConfig(GameLocaizationTable table);
|
void IncreAddLocalizationConfig(GameLocaizationTable table);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 覆盖增加多语言配置
|
/// 覆盖增加多语言配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="table"></param>
|
/// <param name="table"></param>
|
||||||
void CoverAddLocalizationConfig(GameLocaizationTable table);
|
void CoverAddLocalizationConfig(GameLocaizationTable table);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重新加载指定多语言表当前语言的数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="table">目标多语言表。</param>
|
||||||
|
void ReloadLocalizationConfig(GameLocaizationTable table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -3,11 +3,25 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace AlicizaX
|
namespace AlicizaX
|
||||||
{
|
{
|
||||||
public interface IProcedureService:IService, IServiceTickable
|
public interface IProcedureService : IService, IServiceTickable
|
||||||
{
|
{
|
||||||
void InitializeProcedure(List<IProcedure> availableProcedures, Type defaultProcedureType);
|
Type CurrentProcedureType { get; }
|
||||||
|
void InitializeProcedure(IEnumerable<IProcedure> availableProcedures, Type defaultProcedureType);
|
||||||
void ClearAllProcedures();
|
void ClearAllProcedures();
|
||||||
bool SwitchProcedure<T>() where T : IProcedure;
|
bool ContainsProcedure(Type procedureType);
|
||||||
bool SwitchProcedure(Type procedureType);
|
bool TrySwitchProcedure(Type procedureType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ProcedureServiceExtensions
|
||||||
|
{
|
||||||
|
public static bool SwitchProcedure<T>(this IProcedureService procedureService) where T : IProcedure
|
||||||
|
{
|
||||||
|
return procedureService.TrySwitchProcedure(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool SwitchProcedure(this IProcedureService procedureService, Type procedureType)
|
||||||
|
{
|
||||||
|
return procedureService.TrySwitchProcedure(procedureType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
AppServices.GetOrCreateScope<AppScope>().Register(new ProcedureService());
|
AppServices.App.Register(new ProcedureService());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,113 +10,83 @@ namespace AlicizaX
|
|||||||
private IProcedure _currentProcedure;
|
private IProcedure _currentProcedure;
|
||||||
private IProcedure _defaultProcedure;
|
private IProcedure _defaultProcedure;
|
||||||
|
|
||||||
|
public Type CurrentProcedureType => _currentProcedure?.GetType();
|
||||||
|
|
||||||
public void InitializeProcedure(List<IProcedure> availableProcedures, Type defaultProcedureType)
|
public void InitializeProcedure(IEnumerable<IProcedure> availableProcedures, Type defaultProcedureType)
|
||||||
{
|
{
|
||||||
_procedures.Clear();
|
_procedures.Clear();
|
||||||
foreach (var procedure in availableProcedures)
|
foreach (var procedure in availableProcedures)
|
||||||
{
|
{
|
||||||
|
if (procedure == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var type = procedure.GetType();
|
var type = procedure.GetType();
|
||||||
_procedures[type] = procedure;
|
_procedures[type] = procedure;
|
||||||
procedure.ProcedureService = this;
|
procedure.ProcedureService = this;
|
||||||
procedure.Init();
|
procedure.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_procedures.ContainsKey(defaultProcedureType))
|
if (_procedures.TryGetValue(defaultProcedureType, out var defaultProcedure))
|
||||||
{
|
{
|
||||||
_defaultProcedure = _procedures[defaultProcedureType];
|
_defaultProcedure = defaultProcedure;
|
||||||
SwitchProcedure(defaultProcedureType);
|
TrySwitchProcedure(defaultProcedureType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Info($"默认流程 {defaultProcedureType.Name} 未注册!");
|
Log.Info($"榛樿娴佺▼ {defaultProcedureType.Name} 鏈敞鍐?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <summary>
|
|
||||||
/// 清除所有流程
|
|
||||||
/// </summary>
|
|
||||||
public void ClearAllProcedures()
|
public void ClearAllProcedures()
|
||||||
{
|
{
|
||||||
if (_procedures != null)
|
foreach (var procedure in _procedures.Values)
|
||||||
{
|
{
|
||||||
foreach (var procedure in _procedures.Values)
|
procedure.Destroy();
|
||||||
{
|
|
||||||
procedure.Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
_procedures.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_procedures.Clear();
|
||||||
_currentProcedure = null;
|
_currentProcedure = null;
|
||||||
_defaultProcedure = null;
|
_defaultProcedure = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SwitchProcedure<T>() where T : IProcedure
|
public bool ContainsProcedure(Type procedureType)
|
||||||
{
|
{
|
||||||
if (HasProcedure<T>())
|
return procedureType != null && _procedures.ContainsKey(procedureType);
|
||||||
{
|
|
||||||
return SwitchProcedure(typeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_defaultProcedure != null)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"流程 {typeof(T).Name} 不存在,切换到默认流程");
|
|
||||||
return SwitchToDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TrySwitchProcedure(Type procedureType)
|
||||||
public bool SwitchProcedure(Type procedureType)
|
|
||||||
{
|
{
|
||||||
var nextProcedure = _procedures[procedureType];
|
if (procedureType == null)
|
||||||
var lastProcedure = _currentProcedure;
|
|
||||||
|
|
||||||
if (lastProcedure == nextProcedure)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (lastProcedure != null)
|
|
||||||
{
|
{
|
||||||
lastProcedure.Leave();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_procedures.TryGetValue(procedureType, out var nextProcedure))
|
||||||
|
{
|
||||||
|
if (_defaultProcedure == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.LogWarning($"娴佺▼ {procedureType.Name} 涓嶅瓨鍦紝鍒囨崲鍒伴粯璁ゆ祦绋?");
|
||||||
|
nextProcedure = _defaultProcedure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReferenceEquals(_currentProcedure, nextProcedure))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentProcedure?.Leave();
|
||||||
nextProcedure.Enter();
|
nextProcedure.Enter();
|
||||||
_currentProcedure = nextProcedure;
|
_currentProcedure = nextProcedure;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 切换到默认流程
|
|
||||||
/// </summary>
|
|
||||||
private bool SwitchToDefault()
|
|
||||||
{
|
|
||||||
if (_defaultProcedure != null)
|
|
||||||
{
|
|
||||||
return SwitchProcedure(_defaultProcedure.GetType());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查是否存在指定类型的流程
|
|
||||||
/// </summary>
|
|
||||||
private bool HasProcedure<T>() where T : IProcedure
|
|
||||||
{
|
|
||||||
return _procedures.ContainsKey(typeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override void OnInitialize()
|
protected override void OnInitialize()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDestroyService()
|
protected override void OnDestroyService()
|
||||||
@ -126,10 +96,7 @@ namespace AlicizaX
|
|||||||
|
|
||||||
void IServiceTickable.Tick(float deltaTime)
|
void IServiceTickable.Tick(float deltaTime)
|
||||||
{
|
{
|
||||||
if (_currentProcedure != null)
|
_currentProcedure?.Update();
|
||||||
{
|
|
||||||
_currentProcedure.Update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async UniTaskVoid SetAssetByResources<T>(ISetAssetObject setAssetObject, CancellationToken cancellationToken) where T : UnityEngine.Object
|
public async UniTask SetAssetByResources<T>(ISetAssetObject setAssetObject, CancellationToken cancellationToken) where T : UnityEngine.Object
|
||||||
{
|
{
|
||||||
var target = setAssetObject.TargetObject;
|
var target = setAssetObject.TargetObject;
|
||||||
var location = setAssetObject.Location;
|
var location = setAssetObject.Location;
|
||||||
@ -176,6 +176,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
|
UnityEngine.Application.lowMemory -= OnLowMemory;
|
||||||
ReleaseTrackedAssets();
|
ReleaseTrackedAssets();
|
||||||
|
|
||||||
foreach (var state in _loadingStates.Values)
|
foreach (var state in _loadingStates.Values)
|
||||||
@ -186,4 +187,4 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
_loadingStates.Clear();
|
_loadingStates.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,8 +23,6 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
private float checkCanReleaseInterval = 30f;
|
private float checkCanReleaseInterval = 30f;
|
||||||
|
|
||||||
private float _checkCanReleaseTime = 0.0f;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 对象池自动释放时间间隔。
|
/// 对象池自动释放时间间隔。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -37,6 +35,9 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
private int maxProcessPerFrame = 50;
|
private int maxProcessPerFrame = 50;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private int releaseCheckThreshold = 16;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前正在处理的节点,用于分帧处理。
|
/// 当前正在处理的节点,用于分帧处理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -48,6 +49,8 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
private LinkedList<LoadAssetObject> _loadAssetObjectsLinkedList;
|
private LinkedList<LoadAssetObject> _loadAssetObjectsLinkedList;
|
||||||
|
|
||||||
private Dictionary<Object, LinkedListNode<LoadAssetObject>> _trackedAssetNodes;
|
private Dictionary<Object, LinkedListNode<LoadAssetObject>> _trackedAssetNodes;
|
||||||
|
private bool _releaseRequested;
|
||||||
|
private float _nextReleaseCheckTime = float.MaxValue;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 散图集合对象池。
|
/// 散图集合对象池。
|
||||||
@ -65,11 +68,18 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
private IEnumerator Start()
|
private IEnumerator Start()
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
enabled = false;
|
||||||
|
Application.lowMemory += OnLowMemory;
|
||||||
yield return new WaitForEndOfFrame();
|
yield return new WaitForEndOfFrame();
|
||||||
IObjectPoolService objectPoolComponent = AppServices.Require<IObjectPoolService>();
|
IObjectPoolService objectPoolComponent = AppServices.Require<IObjectPoolService>();
|
||||||
_assetItemPool = objectPoolComponent.CreateMultiSpawnObjectPool<AssetItemObject>(
|
_assetItemPool = objectPoolComponent.CreatePool<AssetItemObject>(
|
||||||
"SetAssetPool",
|
new ObjectPoolCreateOptions(
|
||||||
autoReleaseInterval, 16, 60, 0);
|
name: "SetAssetPool",
|
||||||
|
allowMultiSpawn: true,
|
||||||
|
autoReleaseInterval: autoReleaseInterval,
|
||||||
|
capacity: 16,
|
||||||
|
expireTime: 60,
|
||||||
|
priority: 0));
|
||||||
_loadAssetObjectsLinkedList = new LinkedList<LoadAssetObject>();
|
_loadAssetObjectsLinkedList = new LinkedList<LoadAssetObject>();
|
||||||
_trackedAssetNodes = new Dictionary<Object, LinkedListNode<LoadAssetObject>>(16);
|
_trackedAssetNodes = new Dictionary<Object, LinkedListNode<LoadAssetObject>>(16);
|
||||||
|
|
||||||
@ -78,8 +88,13 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
_checkCanReleaseTime += Time.unscaledDeltaTime;
|
if (!_releaseRequested)
|
||||||
if (_checkCanReleaseTime < (double)checkCanReleaseInterval)
|
{
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Time.unscaledTime < _nextReleaseCheckTime)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -96,7 +111,9 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
if (_loadAssetObjectsLinkedList == null || _loadAssetObjectsLinkedList.Count == 0)
|
if (_loadAssetObjectsLinkedList == null || _loadAssetObjectsLinkedList.Count == 0)
|
||||||
{
|
{
|
||||||
_currentProcessNode = null;
|
_currentProcessNode = null;
|
||||||
_checkCanReleaseTime = 0f;
|
_releaseRequested = false;
|
||||||
|
_nextReleaseCheckTime = float.MaxValue;
|
||||||
|
enabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +146,13 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
// 如果已经处理完所有节点,重置状态
|
// 如果已经处理完所有节点,重置状态
|
||||||
if (_currentProcessNode == null)
|
if (_currentProcessNode == null)
|
||||||
{
|
{
|
||||||
_checkCanReleaseTime = 0f;
|
_releaseRequested = false;
|
||||||
|
_nextReleaseCheckTime = float.MaxValue;
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScheduleReleaseSweep(checkCanReleaseInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +167,10 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
setAssetObject.SetAsset(assetObject);
|
setAssetObject.SetAsset(assetObject);
|
||||||
|
if (_loadAssetObjectsLinkedList.Count >= releaseCheckThreshold)
|
||||||
|
{
|
||||||
|
ScheduleReleaseSweep();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReplaceTrackedAsset(Object target)
|
private void ReplaceTrackedAsset(Object target)
|
||||||
@ -188,6 +215,10 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
_loadAssetObjectsLinkedList?.Remove(node);
|
_loadAssetObjectsLinkedList?.Remove(node);
|
||||||
|
if (_loadAssetObjectsLinkedList != null && _loadAssetObjectsLinkedList.Count > 0)
|
||||||
|
{
|
||||||
|
ScheduleReleaseSweep(checkCanReleaseInterval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReleaseTrackedAssets()
|
private void ReleaseTrackedAssets()
|
||||||
@ -207,6 +238,22 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
_currentProcessNode = null;
|
_currentProcessNode = null;
|
||||||
_trackedAssetNodes?.Clear();
|
_trackedAssetNodes?.Clear();
|
||||||
|
_releaseRequested = false;
|
||||||
|
_nextReleaseCheckTime = float.MaxValue;
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ScheduleReleaseSweep(float delay = 0f)
|
||||||
|
{
|
||||||
|
_releaseRequested = true;
|
||||||
|
float dueTime = Time.unscaledTime + Math.Max(0f, delay);
|
||||||
|
_nextReleaseCheckTime = Math.Min(_nextReleaseCheckTime, dueTime);
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLowMemory()
|
||||||
|
{
|
||||||
|
ScheduleReleaseSweep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -151,7 +151,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// <param name="loadAssetCallbacks">加载资源回调函数集。</param>
|
/// <param name="loadAssetCallbacks">加载资源回调函数集。</param>
|
||||||
/// <param name="userData">用户自定义数据。</param>
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
/// <param name="packageName">指定资源包的名称。不传使用默认资源包。</param>
|
/// <param name="packageName">指定资源包的名称。不传使用默认资源包。</param>
|
||||||
void LoadAssetAsync(string location, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "");
|
UniTask LoadAssetAsync(string location, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步加载资源。
|
/// 异步加载资源。
|
||||||
@ -162,7 +162,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// <param name="loadAssetCallbacks">加载资源回调函数集。</param>
|
/// <param name="loadAssetCallbacks">加载资源回调函数集。</param>
|
||||||
/// <param name="userData">用户自定义数据。</param>
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
/// <param name="packageName">指定资源包的名称。不传使用默认资源包。</param>
|
/// <param name="packageName">指定资源包的名称。不传使用默认资源包。</param>
|
||||||
void LoadAssetAsync(string location, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "");
|
UniTask LoadAssetAsync(string location, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 同步加载资源。
|
/// 同步加载资源。
|
||||||
@ -190,7 +190,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// <param name="callback">回调函数。</param>
|
/// <param name="callback">回调函数。</param>
|
||||||
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
|
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
|
||||||
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
||||||
UniTaskVoid LoadAsset<T>(string location, Action<T> callback, string packageName = "") where T : UnityEngine.Object;
|
UniTask LoadAsset<T>(string location, Action<T> callback, string packageName = "") where T : UnityEngine.Object;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步加载资源。
|
/// 异步加载资源。
|
||||||
|
|||||||
@ -7,7 +7,7 @@ using YooAsset;
|
|||||||
namespace AlicizaX.Resource.Runtime
|
namespace AlicizaX.Resource.Runtime
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 资源组件。
|
/// 资源组件<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
public class ResourceComponent : MonoBehaviour
|
public class ResourceComponent : MonoBehaviour
|
||||||
@ -41,24 +41,24 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
[SerializeField] private string decryptionServices = "";
|
[SerializeField] private string decryptionServices = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自动释放资源引用计数为0的资源包
|
/// 自动释放资源引用计数<EFBFBD>?的资源包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeField] public bool autoUnloadBundleWhenUnused = false;
|
[SerializeField] public bool autoUnloadBundleWhenUnused = false;
|
||||||
|
|
||||||
[SerializeField] private EPlayMode _playMode = EPlayMode.EditorSimulateMode;
|
[SerializeField] private EPlayMode _playMode = EPlayMode.EditorSimulateMode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前最新的包裹版本。
|
/// 当前最新的包裹版本<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PackageVersion { set; get; }
|
public string PackageVersion { set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 资源包名称。
|
/// 资源包名称<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeField] private string packageName = "DefaultPackage";
|
[SerializeField] private string packageName = "DefaultPackage";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 资源包名称。
|
/// 资源包名称<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PackageName
|
public string PackageName
|
||||||
{
|
{
|
||||||
@ -75,7 +75,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
public int downloadingMaxNum = 10;
|
public int downloadingMaxNum = 10;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置同时最大下载数目。
|
/// 获取或设置同时最大下载数目<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int DownloadingMaxNum
|
public int DownloadingMaxNum
|
||||||
{
|
{
|
||||||
@ -92,17 +92,17 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前资源适用的游戏版本号。
|
/// 获取当前资源适用的游戏版本号<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ApplicableGameVersion => _resourceService.ApplicableGameVersion;
|
public string ApplicableGameVersion => _resourceService.ApplicableGameVersion;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前内部资源版本号。
|
/// 获取当前内部资源版本号<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int InternalResourceVersion => _resourceService.InternalResourceVersion;
|
public int InternalResourceVersion => _resourceService.InternalResourceVersion;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置无用资源释放的最小间隔时间,以秒为单位。
|
/// 获取或设置无用资源释放的最小间隔时间,以秒为单位<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MinUnloadUnusedAssetsInterval
|
public float MinUnloadUnusedAssetsInterval
|
||||||
{
|
{
|
||||||
@ -111,7 +111,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置无用资源释放的最大间隔时间,以秒为单位。
|
/// 获取或设置无用资源释放的最大间隔时间,以秒为单位<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaxUnloadUnusedAssetsInterval
|
public float MaxUnloadUnusedAssetsInterval
|
||||||
{
|
{
|
||||||
@ -120,7 +120,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 使用系统释放无用资源策略。
|
/// 使用系统释放无用资源策略<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool UseSystemUnloadUnusedAssets
|
public bool UseSystemUnloadUnusedAssets
|
||||||
{
|
{
|
||||||
@ -129,7 +129,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取无用资源释放的等待时长,以秒为单位。
|
/// 获取无用资源释放的等待时长,以秒为单位<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float LastUnloadUnusedAssetsOperationElapseSeconds => _lastUnloadUnusedAssetsOperationElapseSeconds;
|
public float LastUnloadUnusedAssetsOperationElapseSeconds => _lastUnloadUnusedAssetsOperationElapseSeconds;
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
[SerializeField] private int assetPriority = 0;
|
[SerializeField] private int assetPriority = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置资源对象池自动释放可释放对象的间隔秒数。
|
/// 获取或设置资源对象池自动释放可释放对象的间隔秒数<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float AssetAutoReleaseInterval
|
public float AssetAutoReleaseInterval
|
||||||
{
|
{
|
||||||
@ -151,7 +151,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置资源对象池的容量。
|
/// 获取或设置资源对象池的容量<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int AssetCapacity
|
public int AssetCapacity
|
||||||
{
|
{
|
||||||
@ -160,7 +160,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置资源对象池对象过期秒数。
|
/// 获取或设置资源对象池对象过期秒数<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float AssetExpireTime
|
public float AssetExpireTime
|
||||||
{
|
{
|
||||||
@ -169,7 +169,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置资源对象池的优先级。
|
/// 获取或设置资源对象池的优先级<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int AssetPriority
|
public int AssetPriority
|
||||||
{
|
{
|
||||||
@ -191,7 +191,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_resourceService = AppServices.GetOrCreateScope<AppScope>().Register(new ResourceService());
|
_resourceService = AppServices.App.Register(new ResourceService());
|
||||||
|
|
||||||
Application.lowMemory += OnLowMemory;
|
Application.lowMemory += OnLowMemory;
|
||||||
}
|
}
|
||||||
@ -227,9 +227,9 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
#region 释放资源
|
#region 释放资源
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 强制执行释放未被使用的资源。
|
/// 强制执行释放未被使用的资源<EFBFBD>?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="performGCCollect">是否使用垃圾回收。</param>
|
/// <param name="performGCCollect">是否使用垃圾回收<EFBFBD>?/param>
|
||||||
public void ForceUnloadUnusedAssets(bool performGCCollect)
|
public void ForceUnloadUnusedAssets(bool performGCCollect)
|
||||||
{
|
{
|
||||||
_forceUnloadUnusedAssets = true;
|
_forceUnloadUnusedAssets = true;
|
||||||
|
|||||||
@ -61,7 +61,8 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// <param name="objectPoolModule">对象池管理器。</param>
|
/// <param name="objectPoolModule">对象池管理器。</param>
|
||||||
public void CreateAssetPool( )
|
public void CreateAssetPool( )
|
||||||
{
|
{
|
||||||
_assetPool = Context.Require<IObjectPoolService>().CreateMultiSpawnObjectPool<AssetObject>("Asset Pool");
|
_assetPool = Context.Require<IObjectPoolService>().CreatePool<AssetObject>(
|
||||||
|
ObjectPoolCreateOptions.Multi("Asset Pool"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -652,7 +652,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// <param name="callback">回调函数。</param>
|
/// <param name="callback">回调函数。</param>
|
||||||
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
|
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
|
||||||
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
||||||
public async UniTaskVoid LoadAsset<T>(string location, Action<T> callback, string packageName = "") where T : UnityEngine.Object
|
public async UniTask LoadAsset<T>(string location, Action<T> callback, string packageName = "") where T : UnityEngine.Object
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(location))
|
if (string.IsNullOrEmpty(location))
|
||||||
{
|
{
|
||||||
@ -730,7 +730,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// <param name="loadAssetCallbacks">加载资源回调函数集。</param>
|
/// <param name="loadAssetCallbacks">加载资源回调函数集。</param>
|
||||||
/// <param name="userData">用户自定义数据。</param>
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
/// <param name="packageName">指定资源包的名称。不传使用默认资源包。</param>
|
/// <param name="packageName">指定资源包的名称。不传使用默认资源包。</param>
|
||||||
public async void LoadAssetAsync(string location, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "")
|
public async UniTask LoadAssetAsync(string location, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "")
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(location))
|
if (string.IsNullOrEmpty(location))
|
||||||
{
|
{
|
||||||
@ -800,7 +800,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// <param name="loadAssetCallbacks">加载资源回调函数集。</param>
|
/// <param name="loadAssetCallbacks">加载资源回调函数集。</param>
|
||||||
/// <param name="userData">用户自定义数据。</param>
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
/// <param name="packageName">指定资源包的名称。不传使用默认资源包。</param>
|
/// <param name="packageName">指定资源包的名称。不传使用默认资源包。</param>
|
||||||
public async void LoadAssetAsync(string location, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "")
|
public async UniTask LoadAssetAsync(string location, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "")
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(location))
|
if (string.IsNullOrEmpty(location))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,41 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
using AlicizaX.Resource.Runtime;
|
|
||||||
using AlicizaX;
|
using AlicizaX;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using YooAsset;
|
|
||||||
|
|
||||||
namespace AlicizaX.Scene.Runtime
|
namespace AlicizaX.Scene.Runtime
|
||||||
{
|
{
|
||||||
public interface ISceneService : IService
|
public interface ISceneService : IService
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 当前主场景名称。
|
|
||||||
/// </summary>
|
|
||||||
public string CurrentMainSceneName { get; }
|
public string CurrentMainSceneName { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景的定位地址</param>
|
|
||||||
/// <param name="sceneMode">场景加载模式</param>
|
|
||||||
/// <param name="suspendLoad">加载完毕时是否主动挂起</param>
|
|
||||||
/// <param name="priority">优先级</param>
|
|
||||||
/// <param name="gcCollect">加载主场景是否回收垃圾。</param>
|
|
||||||
/// <param name="progressCallBack">加载进度回调。</param>
|
|
||||||
public UniTask<UnityEngine.SceneManagement.Scene> LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true,
|
public UniTask<UnityEngine.SceneManagement.Scene> LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true,
|
||||||
Action<float> progressCallBack = null);
|
Action<float> progressCallBack = null);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景的定位地址</param>
|
|
||||||
/// <param name="sceneMode">场景加载模式</param>
|
|
||||||
/// <param name="suspendLoad">加载完毕时是否主动挂起</param>
|
|
||||||
/// <param name="priority">优先级</param>
|
|
||||||
/// <param name="callBack">加载回调。</param>
|
|
||||||
/// <param name="gcCollect">加载主场景是否回收垃圾。</param>
|
|
||||||
/// <param name="progressCallBack">加载进度回调。</param>
|
|
||||||
public void LoadScene(string location,
|
public void LoadScene(string location,
|
||||||
LoadSceneMode sceneMode = LoadSceneMode.Single,
|
LoadSceneMode sceneMode = LoadSceneMode.Single,
|
||||||
bool suspendLoad = false,
|
bool suspendLoad = false,
|
||||||
@ -44,47 +20,25 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
bool gcCollect = true,
|
bool gcCollect = true,
|
||||||
Action<float> progressCallBack = null);
|
Action<float> progressCallBack = null);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 激活场景(当同时存在多个场景时用于切换激活场景)。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <returns>是否操作成功。</returns>
|
|
||||||
public bool ActivateScene(string location);
|
public bool ActivateScene(string location);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 解除场景加载挂起操作。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <returns>是否操作成功。</returns>
|
|
||||||
public bool UnSuspend(string location);
|
public bool UnSuspend(string location);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否为主场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <returns>是否主场景。</returns>
|
|
||||||
public bool IsMainScene(string location);
|
public bool IsMainScene(string location);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步卸载子场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <param name="progressCallBack">进度回调。</param>
|
|
||||||
public UniTask<bool> UnloadAsync(string location, Action<float> progressCallBack = null);
|
public UniTask<bool> UnloadAsync(string location, Action<float> progressCallBack = null);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步卸载子场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <param name="callBack">卸载完成回调。</param>
|
|
||||||
/// <param name="progressCallBack">进度回调。</param>
|
|
||||||
public void Unload(string location, Action callBack = null, Action<float> progressCallBack = null);
|
public void Unload(string location, Action callBack = null, Action<float> progressCallBack = null);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否包含场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <returns>是否包含场景。</returns>
|
|
||||||
public bool IsContainScene(string location);
|
public bool IsContainScene(string location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ISceneStateService : IService
|
||||||
|
{
|
||||||
|
public string CurrentMainSceneName { get; }
|
||||||
|
|
||||||
|
public bool IsContainScene(string location);
|
||||||
|
|
||||||
|
public bool IsMainScene(string location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using AlicizaX;
|
using AlicizaX;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -10,7 +9,12 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
{
|
{
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
AppServices.GetOrCreateScope<AppScope>().Register(new SceneService());
|
if (!AppServices.App.TryGet<ISceneService>(out _))
|
||||||
|
{
|
||||||
|
AppServices.App.Register(new SceneService());
|
||||||
|
}
|
||||||
|
|
||||||
|
AppServices.EnsureScene();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,56 +9,22 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
{
|
{
|
||||||
internal class SceneService : ServiceBase, ISceneService
|
internal class SceneService : ServiceBase, ISceneService
|
||||||
{
|
{
|
||||||
private string _currentMainSceneName = string.Empty;
|
public string CurrentMainSceneName => EnsureSceneState().CurrentMainSceneName;
|
||||||
|
|
||||||
private SceneHandle _currentMainScene;
|
|
||||||
|
|
||||||
private readonly Dictionary<string, SceneHandle> _subScenes = new Dictionary<string, SceneHandle>();
|
|
||||||
|
|
||||||
private readonly HashSet<string> _handlingScene = new HashSet<string>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前主场景名称。
|
|
||||||
/// </summary>
|
|
||||||
public string CurrentMainSceneName => _currentMainSceneName;
|
|
||||||
|
|
||||||
protected override void OnInitialize()
|
protected override void OnInitialize()
|
||||||
{
|
{
|
||||||
_currentMainScene = null;
|
var activeScene = SceneManager.GetActiveScene();
|
||||||
_currentMainSceneName = SceneManager.GetSceneByBuildIndex(0).name;
|
EnsureSceneState().SetBootScene(activeScene.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDestroyService()
|
protected override void OnDestroyService()
|
||||||
{
|
{
|
||||||
var iter = _subScenes.Values.GetEnumerator();
|
|
||||||
while (iter.MoveNext())
|
|
||||||
{
|
|
||||||
SceneHandle subScene = iter.Current;
|
|
||||||
if (subScene != null)
|
|
||||||
{
|
|
||||||
subScene.UnloadAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iter.Dispose();
|
|
||||||
_subScenes.Clear();
|
|
||||||
_handlingScene.Clear();
|
|
||||||
_currentMainSceneName = string.Empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景的定位地址</param>
|
|
||||||
/// <param name="sceneMode">场景加载模式</param>
|
|
||||||
/// <param name="suspendLoad">加载完毕时是否主动挂起</param>
|
|
||||||
/// <param name="priority">优先级</param>
|
|
||||||
/// <param name="gcCollect">加载主场景是否回收垃圾。</param>
|
|
||||||
/// <param name="progressCallBack">加载进度回调。</param>
|
|
||||||
public async UniTask<UnityEngine.SceneManagement.Scene> LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, Action<float> progressCallBack = null)
|
public async UniTask<UnityEngine.SceneManagement.Scene> LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, Action<float> progressCallBack = null)
|
||||||
{
|
{
|
||||||
if (!_handlingScene.Add(location))
|
var sceneState = EnsureSceneState();
|
||||||
|
if (!sceneState.TryBeginHandling(location))
|
||||||
{
|
{
|
||||||
Log.Error($"Could not load scene while loading. Scene: {location}");
|
Log.Error($"Could not load scene while loading. Scene: {location}");
|
||||||
return default;
|
return default;
|
||||||
@ -66,15 +32,13 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
|
|
||||||
if (sceneMode == LoadSceneMode.Additive)
|
if (sceneMode == LoadSceneMode.Additive)
|
||||||
{
|
{
|
||||||
if (_subScenes.TryGetValue(location, out SceneHandle subScene))
|
if (sceneState.TryGetSubScene(location, out SceneHandle loadedSubScene))
|
||||||
{
|
{
|
||||||
throw new Exception($"Could not load subScene while already loaded. Scene: {location}");
|
throw new Exception($"Could not load subScene while already loaded. Scene: {location}");
|
||||||
}
|
}
|
||||||
|
|
||||||
subScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
|
var subScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
|
||||||
|
sceneState.AddSubScene(location, subScene);
|
||||||
//Fix 这里前置,subScene.IsDone在UnSupendLoad之后才会是true
|
|
||||||
_subScenes.Add(location, subScene);
|
|
||||||
|
|
||||||
if (progressCallBack != null)
|
if (progressCallBack != null)
|
||||||
{
|
{
|
||||||
@ -89,57 +53,43 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
await subScene.ToUniTask();
|
await subScene.ToUniTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
_handlingScene.Remove(location);
|
sceneState.EndHandling(location);
|
||||||
|
|
||||||
return subScene.SceneObject;
|
return subScene.SceneObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sceneState.CurrentMainSceneHandle is { IsDone: false })
|
||||||
|
{
|
||||||
|
throw new Exception($"Could not load MainScene while loading. CurrentMainScene: {sceneState.CurrentMainSceneName}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
sceneState = PrepareSceneStateForMainSceneLoad(location);
|
||||||
|
var mainSceneHandle = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
|
||||||
|
|
||||||
|
if (progressCallBack != null)
|
||||||
|
{
|
||||||
|
while (!mainSceneHandle.IsDone && mainSceneHandle.IsValid)
|
||||||
|
{
|
||||||
|
progressCallBack.Invoke(mainSceneHandle.Progress);
|
||||||
|
await UniTask.Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_currentMainScene is { IsDone: false })
|
await mainSceneHandle.ToUniTask();
|
||||||
{
|
|
||||||
throw new Exception($"Could not load MainScene while loading. CurrentMainScene: {_currentMainSceneName}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentMainSceneName = location;
|
|
||||||
|
|
||||||
_currentMainScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
|
|
||||||
|
|
||||||
if (progressCallBack != null)
|
|
||||||
{
|
|
||||||
while (!_currentMainScene.IsDone && _currentMainScene.IsValid)
|
|
||||||
{
|
|
||||||
progressCallBack.Invoke(_currentMainScene.Progress);
|
|
||||||
await UniTask.Yield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await _currentMainScene.ToUniTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
Context.Require<IResourceService>().ForceUnloadUnusedAssets(gcCollect);
|
|
||||||
|
|
||||||
_handlingScene.Remove(location);
|
|
||||||
|
|
||||||
return _currentMainScene.SceneObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sceneState.SetMainScene(location, mainSceneHandle);
|
||||||
|
Context.Require<IResourceService>().ForceUnloadUnusedAssets(gcCollect);
|
||||||
|
sceneState.EndHandling(location);
|
||||||
|
return mainSceneHandle.SceneObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景的定位地址</param>
|
|
||||||
/// <param name="sceneMode">场景加载模式</param>
|
|
||||||
/// <param name="suspendLoad">加载完毕时是否主动挂起</param>
|
|
||||||
/// <param name="priority">优先级</param>
|
|
||||||
/// <param name="callBack">加载回调。</param>
|
|
||||||
/// <param name="gcCollect">加载主场景是否回收垃圾。</param>
|
|
||||||
/// <param name="progressCallBack">加载进度回调。</param>
|
|
||||||
public void LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100,
|
public void LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100,
|
||||||
Action<UnityEngine.SceneManagement.Scene> callBack = null,
|
Action<UnityEngine.SceneManagement.Scene> callBack = null,
|
||||||
bool gcCollect = true, Action<float> progressCallBack = null)
|
bool gcCollect = true, Action<float> progressCallBack = null)
|
||||||
{
|
{
|
||||||
if (!_handlingScene.Add(location))
|
var sceneState = EnsureSceneState();
|
||||||
|
if (!sceneState.TryBeginHandling(location))
|
||||||
{
|
{
|
||||||
Log.Error($"Could not load scene while loading. Scene: {location}");
|
Log.Error($"Could not load scene while loading. Scene: {location}");
|
||||||
return;
|
return;
|
||||||
@ -147,88 +97,60 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
|
|
||||||
if (sceneMode == LoadSceneMode.Additive)
|
if (sceneMode == LoadSceneMode.Additive)
|
||||||
{
|
{
|
||||||
if (_subScenes.TryGetValue(location, out SceneHandle subScene))
|
if (sceneState.TryGetSubScene(location, out SceneHandle loadedSubScene))
|
||||||
{
|
{
|
||||||
Log.Warning($"Could not load subScene while already loaded. Scene: {location}");
|
Log.Warning($"Could not load subScene while already loaded. Scene: {location}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
subScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
|
var subScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
|
||||||
|
sceneState.AddSubScene(location, subScene);
|
||||||
subScene.Completed += handle =>
|
subScene.Completed += handle =>
|
||||||
{
|
{
|
||||||
_handlingScene.Remove(location);
|
sceneState.EndHandling(location);
|
||||||
callBack?.Invoke(handle.SceneObject);
|
callBack?.Invoke(handle.SceneObject);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (progressCallBack != null)
|
if (progressCallBack != null)
|
||||||
{
|
{
|
||||||
InvokeProgress(subScene, progressCallBack).Forget();
|
InvokeSceneProgress(subScene, progressCallBack).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
_subScenes.Add(location, subScene);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_currentMainScene is { IsDone: false })
|
|
||||||
{
|
|
||||||
Log.Warning($"Could not load MainScene while loading. CurrentMainScene: {_currentMainSceneName}.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentMainSceneName = location;
|
|
||||||
|
|
||||||
_currentMainScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
|
|
||||||
|
|
||||||
_currentMainScene.Completed += handle =>
|
|
||||||
{
|
|
||||||
_handlingScene.Remove(location);
|
|
||||||
callBack?.Invoke(handle.SceneObject);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (progressCallBack != null)
|
|
||||||
{
|
|
||||||
InvokeProgress(_currentMainScene, progressCallBack).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
Context.Require<IResourceService>().ForceUnloadUnusedAssets(gcCollect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async UniTaskVoid InvokeProgress(SceneHandle sceneHandle, Action<float> progress)
|
|
||||||
{
|
|
||||||
if (sceneHandle == null)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!sceneHandle.IsDone && sceneHandle.IsValid)
|
if (sceneState.CurrentMainSceneHandle is { IsDone: false })
|
||||||
{
|
{
|
||||||
await UniTask.Yield();
|
Log.Warning($"Could not load MainScene while loading. CurrentMainScene: {sceneState.CurrentMainSceneName}.");
|
||||||
|
return;
|
||||||
progress?.Invoke(sceneHandle.Progress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sceneState = PrepareSceneStateForMainSceneLoad(location);
|
||||||
|
var mainSceneHandle = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
|
||||||
|
mainSceneHandle.Completed += handle =>
|
||||||
|
{
|
||||||
|
sceneState.SetMainScene(location, handle);
|
||||||
|
sceneState.EndHandling(location);
|
||||||
|
callBack?.Invoke(handle.SceneObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (progressCallBack != null)
|
||||||
|
{
|
||||||
|
InvokeSceneProgress(mainSceneHandle, progressCallBack).Forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
Context.Require<IResourceService>().ForceUnloadUnusedAssets(gcCollect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 激活场景(当同时存在多个场景时用于切换激活场景)。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <returns>是否操作成功。</returns>
|
|
||||||
public bool ActivateScene(string location)
|
public bool ActivateScene(string location)
|
||||||
{
|
{
|
||||||
if (_currentMainSceneName.Equals(location))
|
var sceneState = EnsureSceneState();
|
||||||
|
if (sceneState.CurrentMainSceneName.Equals(location))
|
||||||
{
|
{
|
||||||
if (_currentMainScene != null)
|
return sceneState.CurrentMainSceneHandle != null && sceneState.CurrentMainSceneHandle.ActivateScene();
|
||||||
{
|
|
||||||
return _currentMainScene.ActivateScene();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_subScenes.TryGetValue(location, out SceneHandle subScene);
|
if (sceneState.TryGetSubScene(location, out var subScene) && subScene != null)
|
||||||
if (subScene != null)
|
|
||||||
{
|
{
|
||||||
return subScene.ActivateScene();
|
return subScene.ActivateScene();
|
||||||
}
|
}
|
||||||
@ -237,25 +159,16 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 解除场景加载挂起操作。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <returns>是否操作成功。</returns>
|
|
||||||
public bool UnSuspend(string location)
|
public bool UnSuspend(string location)
|
||||||
{
|
{
|
||||||
if (_currentMainSceneName.Equals(location))
|
var sceneState = EnsureSceneState();
|
||||||
|
if (sceneState.CurrentMainSceneName.Equals(location))
|
||||||
{
|
{
|
||||||
if (_currentMainScene != null)
|
return sceneState.CurrentMainSceneHandle != null && sceneState.CurrentMainSceneHandle.UnSuspend();
|
||||||
{
|
|
||||||
return _currentMainScene.UnSuspend();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_subScenes.TryGetValue(location, out SceneHandle subScene);
|
if (sceneState.TryGetSubScene(location, out var subScene) && subScene != null)
|
||||||
if (subScene != null)
|
|
||||||
{
|
{
|
||||||
return subScene.UnSuspend();
|
return subScene.UnSuspend();
|
||||||
}
|
}
|
||||||
@ -264,34 +177,27 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否为主场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <returns>是否主场景。</returns>
|
|
||||||
public bool IsMainScene(string location)
|
public bool IsMainScene(string location)
|
||||||
{
|
{
|
||||||
// 获取当前激活的场景
|
var sceneState = EnsureSceneState();
|
||||||
UnityEngine.SceneManagement.Scene currentScene = SceneManager.GetActiveScene();
|
var currentScene = SceneManager.GetActiveScene();
|
||||||
|
|
||||||
if (_currentMainSceneName.Equals(location))
|
if (sceneState.CurrentMainSceneName.Equals(location))
|
||||||
{
|
{
|
||||||
if (_currentMainScene == null)
|
if (sceneState.CurrentMainSceneHandle == null)
|
||||||
{
|
{
|
||||||
return false;
|
return currentScene.name == location;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断当前场景是否是主场景
|
if (currentScene.name == sceneState.CurrentMainSceneHandle.SceneName)
|
||||||
if (currentScene.name == _currentMainScene.SceneName)
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _currentMainScene.SceneName == currentScene.name;
|
return sceneState.CurrentMainSceneHandle.SceneName == currentScene.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断当前场景是否是主场景
|
if (currentScene.name == sceneState.CurrentMainSceneHandle?.SceneName)
|
||||||
if (currentScene.name == _currentMainScene?.SceneName)
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -300,15 +206,10 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步卸载子场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <param name="progressCallBack">进度回调。</param>
|
|
||||||
public async UniTask<bool> UnloadAsync(string location, Action<float> progressCallBack = null)
|
public async UniTask<bool> UnloadAsync(string location, Action<float> progressCallBack = null)
|
||||||
{
|
{
|
||||||
_subScenes.TryGetValue(location, out SceneHandle subScene);
|
var sceneState = EnsureSceneState();
|
||||||
if (subScene != null)
|
if (sceneState.TryGetSubScene(location, out var subScene) && subScene != null)
|
||||||
{
|
{
|
||||||
if (subScene.SceneObject == default)
|
if (subScene.SceneObject == default)
|
||||||
{
|
{
|
||||||
@ -316,14 +217,13 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_handlingScene.Add(location))
|
if (!sceneState.TryBeginHandling(location))
|
||||||
{
|
{
|
||||||
Log.Warning($"Could not unload Scene while loading. Scene: {location}");
|
Log.Warning($"Could not unload Scene while loading. Scene: {location}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var unloadOperation = subScene.UnloadAsync();
|
var unloadOperation = subScene.UnloadAsync();
|
||||||
|
|
||||||
if (progressCallBack != null)
|
if (progressCallBack != null)
|
||||||
{
|
{
|
||||||
while (!unloadOperation.IsDone && unloadOperation.Status != EOperationStatus.Failed)
|
while (!unloadOperation.IsDone && unloadOperation.Status != EOperationStatus.Failed)
|
||||||
@ -337,10 +237,8 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
await unloadOperation.ToUniTask();
|
await unloadOperation.ToUniTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
_subScenes.Remove(location);
|
sceneState.RemoveSubScene(location);
|
||||||
|
sceneState.EndHandling(location);
|
||||||
_handlingScene.Remove(location);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,16 +246,10 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步卸载子场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <param name="callBack">卸载完成回调。</param>
|
|
||||||
/// <param name="progressCallBack">进度回调。</param>
|
|
||||||
public void Unload(string location, Action callBack = null, Action<float> progressCallBack = null)
|
public void Unload(string location, Action callBack = null, Action<float> progressCallBack = null)
|
||||||
{
|
{
|
||||||
_subScenes.TryGetValue(location, out SceneHandle subScene);
|
var sceneState = EnsureSceneState();
|
||||||
if (subScene != null)
|
if (sceneState.TryGetSubScene(location, out var subScene) && subScene != null)
|
||||||
{
|
{
|
||||||
if (subScene.SceneObject == default)
|
if (subScene.SceneObject == default)
|
||||||
{
|
{
|
||||||
@ -365,23 +257,23 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_handlingScene.Add(location))
|
if (!sceneState.TryBeginHandling(location))
|
||||||
{
|
{
|
||||||
Log.Warning($"Could not unload Scene while loading. Scene: {location}");
|
Log.Warning($"Could not unload Scene while loading. Scene: {location}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
subScene.UnloadAsync();
|
var unloadOperation = subScene.UnloadAsync();
|
||||||
subScene.UnloadAsync().Completed += @base =>
|
unloadOperation.Completed += @base =>
|
||||||
{
|
{
|
||||||
_subScenes.Remove(location);
|
sceneState.RemoveSubScene(location);
|
||||||
_handlingScene.Remove(location);
|
sceneState.EndHandling(location);
|
||||||
callBack?.Invoke();
|
callBack?.Invoke();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (progressCallBack != null)
|
if (progressCallBack != null)
|
||||||
{
|
{
|
||||||
InvokeProgress(subScene, progressCallBack).Forget();
|
InvokeOperationProgress(unloadOperation, progressCallBack).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -390,19 +282,140 @@ namespace AlicizaX.Scene.Runtime
|
|||||||
Log.Warning($"UnloadAsync invalid location:{location}");
|
Log.Warning($"UnloadAsync invalid location:{location}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否包含场景。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">场景资源定位地址。</param>
|
|
||||||
/// <returns>是否包含场景。</returns>
|
|
||||||
public bool IsContainScene(string location)
|
public bool IsContainScene(string location)
|
||||||
{
|
{
|
||||||
if (_currentMainSceneName.Equals(location))
|
return EnsureSceneState().IsContainScene(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SceneDomainStateService EnsureSceneState()
|
||||||
|
{
|
||||||
|
var sceneScope = Context.EnsureScene();
|
||||||
|
if (!sceneScope.TryGet<SceneDomainStateService>(out var sceneState))
|
||||||
|
{
|
||||||
|
sceneState = sceneScope.Register(new SceneDomainStateService());
|
||||||
|
}
|
||||||
|
|
||||||
|
return sceneState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SceneDomainStateService PrepareSceneStateForMainSceneLoad(string location)
|
||||||
|
{
|
||||||
|
var sceneScope = Context.ResetScene();
|
||||||
|
var sceneState = sceneScope.Register(new SceneDomainStateService());
|
||||||
|
sceneState.MarkMainSceneLoading(location);
|
||||||
|
return sceneState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async UniTaskVoid InvokeSceneProgress(SceneHandle sceneHandle, Action<float> progress)
|
||||||
|
{
|
||||||
|
if (sceneHandle == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!sceneHandle.IsDone && sceneHandle.IsValid)
|
||||||
|
{
|
||||||
|
await UniTask.Yield();
|
||||||
|
progress?.Invoke(sceneHandle.Progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async UniTaskVoid InvokeOperationProgress(AsyncOperationBase operation, Action<float> progress)
|
||||||
|
{
|
||||||
|
if (operation == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!operation.IsDone && operation.Status != EOperationStatus.Failed)
|
||||||
|
{
|
||||||
|
await UniTask.Yield();
|
||||||
|
progress?.Invoke(operation.Progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class SceneDomainStateService : ServiceBase, ISceneStateService
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, SceneHandle> _subScenes = new Dictionary<string, SceneHandle>();
|
||||||
|
private readonly HashSet<string> _handlingScenes = new HashSet<string>();
|
||||||
|
|
||||||
|
public string CurrentMainSceneName { get; private set; } = string.Empty;
|
||||||
|
|
||||||
|
public SceneHandle CurrentMainSceneHandle { get; private set; }
|
||||||
|
|
||||||
|
protected override void OnInitialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDestroyService()
|
||||||
|
{
|
||||||
|
foreach (var subScene in _subScenes.Values)
|
||||||
|
{
|
||||||
|
subScene?.UnloadAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
_subScenes.Clear();
|
||||||
|
_handlingScenes.Clear();
|
||||||
|
CurrentMainSceneHandle = null;
|
||||||
|
CurrentMainSceneName = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetBootScene(string sceneName)
|
||||||
|
{
|
||||||
|
CurrentMainSceneName = sceneName ?? string.Empty;
|
||||||
|
CurrentMainSceneHandle = null;
|
||||||
|
_subScenes.Clear();
|
||||||
|
_handlingScenes.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkMainSceneLoading(string sceneName)
|
||||||
|
{
|
||||||
|
CurrentMainSceneName = sceneName ?? string.Empty;
|
||||||
|
CurrentMainSceneHandle = null;
|
||||||
|
_handlingScenes.Clear();
|
||||||
|
TryBeginHandling(sceneName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMainScene(string sceneName, SceneHandle sceneHandle)
|
||||||
|
{
|
||||||
|
CurrentMainSceneName = sceneName ?? string.Empty;
|
||||||
|
CurrentMainSceneHandle = sceneHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryBeginHandling(string location)
|
||||||
|
=> !string.IsNullOrEmpty(location) && _handlingScenes.Add(location);
|
||||||
|
|
||||||
|
public void EndHandling(string location)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(location))
|
||||||
|
{
|
||||||
|
_handlingScenes.Remove(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSubScene(string location, SceneHandle sceneHandle)
|
||||||
|
{
|
||||||
|
_subScenes[location] = sceneHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetSubScene(string location, out SceneHandle sceneHandle)
|
||||||
|
=> _subScenes.TryGetValue(location, out sceneHandle);
|
||||||
|
|
||||||
|
public bool RemoveSubScene(string location)
|
||||||
|
=> _subScenes.Remove(location);
|
||||||
|
|
||||||
|
public bool IsContainScene(string location)
|
||||||
|
{
|
||||||
|
if (CurrentMainSceneName.Equals(location))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _subScenes.TryGetValue(location, out var _);
|
return _subScenes.ContainsKey(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsMainScene(string location)
|
||||||
|
=> CurrentMainSceneName.Equals(location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,8 @@ namespace AlicizaX.Timer.Runtime
|
|||||||
{
|
{
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
AppServices.GetOrCreateScope<AppScope>().Register(new TimerService());
|
AppServices.App.Register(new TimerService());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ namespace AlicizaX.UI.Runtime
|
|||||||
public static class UIHolderFactory
|
public static class UIHolderFactory
|
||||||
{
|
{
|
||||||
private static IResourceService ResourceService => AppServices.Require<IResourceService>();
|
private static IResourceService ResourceService => AppServices.Require<IResourceService>();
|
||||||
|
private static bool AllowLegacyResourcesFallback => UnityEngine.Application.isEditor || UnityEngine.Debug.isDebugBuild;
|
||||||
|
|
||||||
public static async UniTask<T> CreateUIHolderAsync<T>(Transform parent) where T : UIHolderObjectBase
|
public static async UniTask<T> CreateUIHolderAsync<T>(Transform parent) where T : UIHolderObjectBase
|
||||||
{
|
{
|
||||||
@ -41,14 +42,14 @@ namespace AlicizaX.UI.Runtime
|
|||||||
{
|
{
|
||||||
return resInfo.LoadType == EUIResLoadType.AssetBundle
|
return resInfo.LoadType == EUIResLoadType.AssetBundle
|
||||||
? await ResourceService.LoadGameObjectAsync(resInfo.Location, parent)
|
? await ResourceService.LoadGameObjectAsync(resInfo.Location, parent)
|
||||||
: await InstantiateResourceAsync(resInfo.Location, parent);
|
: await LoadResourceWithFallbackAsync(resInfo.Location, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static GameObject LoadUIResourcesSync(UIResRegistry.UIResInfo resInfo, Transform parent)
|
internal static GameObject LoadUIResourcesSync(UIResRegistry.UIResInfo resInfo, Transform parent)
|
||||||
{
|
{
|
||||||
return resInfo.LoadType == EUIResLoadType.AssetBundle
|
return resInfo.LoadType == EUIResLoadType.AssetBundle
|
||||||
? ResourceService.LoadGameObject(resInfo.Location, parent)
|
? ResourceService.LoadGameObject(resInfo.Location, parent)
|
||||||
: InstantiateResourceSync(resInfo.Location, parent);
|
: LoadResourceWithFallbackSync(resInfo.Location, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -88,6 +89,58 @@ namespace AlicizaX.UI.Runtime
|
|||||||
return Object.Instantiate(prefab, parent);
|
return Object.Instantiate(prefab, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async UniTask<GameObject> LoadResourceWithFallbackAsync(string location, Transform parent)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var managedObject = await ResourceService.LoadGameObjectAsync(location, parent);
|
||||||
|
if (managedObject != null)
|
||||||
|
{
|
||||||
|
return managedObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (!AllowLegacyResourcesFallback)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AllowLegacyResourcesFallback)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException($"UI resource load failed via IResourceService: {location}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return await InstantiateResourceAsync(location, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject LoadResourceWithFallbackSync(string location, Transform parent)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var managedObject = ResourceService.LoadGameObject(location, parent);
|
||||||
|
if (managedObject != null)
|
||||||
|
{
|
||||||
|
return managedObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (!AllowLegacyResourcesFallback)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AllowLegacyResourcesFallback)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException($"UI resource load failed via IResourceService: {location}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return InstantiateResourceSync(location, parent);
|
||||||
|
}
|
||||||
|
|
||||||
private static void ValidateAndBind(UIMetadata meta, GameObject holderObject, UIBase owner)
|
private static void ValidateAndBind(UIMetadata meta, GameObject holderObject, UIBase owner)
|
||||||
{
|
{
|
||||||
if (!holderObject) throw new NullReferenceException($"UI resource load failed: {meta.ResInfo.Location}");
|
if (!holderObject) throw new NullReferenceException($"UI resource load failed: {meta.ResInfo.Location}");
|
||||||
|
|||||||
@ -13,7 +13,14 @@ namespace AlicizaX.UI.Runtime
|
|||||||
|
|
||||||
static UIMetadataFactory()
|
static UIMetadataFactory()
|
||||||
{
|
{
|
||||||
m_UIMetadataPool = AppServices.Require<IObjectPoolService>().CreateSingleSpawnObjectPool<UIMetadataObject>("UI Metadata Pool", 60, 16, 60f, 0);
|
m_UIMetadataPool = AppServices.Require<IObjectPoolService>().CreatePool<UIMetadataObject>(
|
||||||
|
new ObjectPoolCreateOptions(
|
||||||
|
name: "UI Metadata Pool",
|
||||||
|
allowMultiSpawn: false,
|
||||||
|
autoReleaseInterval: 60,
|
||||||
|
capacity: 16,
|
||||||
|
expireTime: 60f,
|
||||||
|
priority: 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static UIMetadata GetWindowMetadata<T>()
|
internal static UIMetadata GetWindowMetadata<T>()
|
||||||
|
|||||||
@ -7,17 +7,17 @@ using Cysharp.Threading.Tasks;
|
|||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
namespace AlicizaX.UI.Runtime
|
||||||
{
|
{
|
||||||
readonly struct LayerData
|
sealed class LayerData
|
||||||
{
|
{
|
||||||
public readonly List<UIMetadata> OrderList; // 维护插入顺序
|
public readonly List<UIMetadata> OrderList;
|
||||||
public readonly HashSet<RuntimeTypeHandle> HandleSet; // O(1)存在性检查
|
public readonly Dictionary<RuntimeTypeHandle, int> IndexMap;
|
||||||
public readonly Dictionary<RuntimeTypeHandle, int> IndexMap; // O(1)索引查找
|
public int LastFullscreenIndex;
|
||||||
|
|
||||||
public LayerData(int initialCapacity)
|
public LayerData(int initialCapacity)
|
||||||
{
|
{
|
||||||
OrderList = new List<UIMetadata>(initialCapacity);
|
OrderList = new List<UIMetadata>(initialCapacity);
|
||||||
HandleSet = new HashSet<RuntimeTypeHandle>();
|
|
||||||
IndexMap = new Dictionary<RuntimeTypeHandle, int>(initialCapacity);
|
IndexMap = new Dictionary<RuntimeTypeHandle, int>(initialCapacity);
|
||||||
|
LastFullscreenIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,9 +70,9 @@ namespace AlicizaX.UI.Runtime
|
|||||||
if (meta.State == UIState.Loaded || meta.State == UIState.Initialized)
|
if (meta.State == UIState.Loaded || meta.State == UIState.Initialized)
|
||||||
{
|
{
|
||||||
meta.CancelAsyncOperations();
|
meta.CancelAsyncOperations();
|
||||||
Pop(meta);
|
var popResult = Pop(meta);
|
||||||
SortWindowVisible(meta.MetaInfo.UILayer);
|
SortWindowVisible(meta.MetaInfo.UILayer, popResult.previousFullscreenIndex);
|
||||||
SortWindowDepth(meta.MetaInfo.UILayer);
|
SortWindowDepth(meta.MetaInfo.UILayer, popResult.removedIndex >= 0 ? popResult.removedIndex : 0);
|
||||||
meta.View.Visible = false;
|
meta.View.Visible = false;
|
||||||
CacheWindow(meta, force);
|
CacheWindow(meta, force);
|
||||||
return;
|
return;
|
||||||
@ -85,9 +85,9 @@ namespace AlicizaX.UI.Runtime
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pop(meta);
|
var closedPopResult = Pop(meta);
|
||||||
SortWindowVisible(meta.MetaInfo.UILayer);
|
SortWindowVisible(meta.MetaInfo.UILayer, closedPopResult.previousFullscreenIndex);
|
||||||
SortWindowDepth(meta.MetaInfo.UILayer);
|
SortWindowDepth(meta.MetaInfo.UILayer, closedPopResult.removedIndex >= 0 ? closedPopResult.removedIndex : 0);
|
||||||
CacheWindow(meta, force);
|
CacheWindow(meta, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,35 +132,42 @@ namespace AlicizaX.UI.Runtime
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void Push(UIMetadata meta)
|
private void Push(UIMetadata meta)
|
||||||
{
|
{
|
||||||
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
|
var layer = _openUI[meta.MetaInfo.UILayer];
|
||||||
if (layer.HandleSet.Add(meta.MetaInfo.RuntimeTypeHandle))
|
if (!layer.IndexMap.ContainsKey(meta.MetaInfo.RuntimeTypeHandle))
|
||||||
{
|
{
|
||||||
int index = layer.OrderList.Count;
|
int index = layer.OrderList.Count;
|
||||||
layer.OrderList.Add(meta);
|
layer.OrderList.Add(meta);
|
||||||
layer.IndexMap[meta.MetaInfo.RuntimeTypeHandle] = index;
|
layer.IndexMap[meta.MetaInfo.RuntimeTypeHandle] = index;
|
||||||
|
if (meta.MetaInfo.FullScreen)
|
||||||
|
{
|
||||||
|
layer.LastFullscreenIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateLayerParent(meta);
|
UpdateLayerParent(meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void Pop(UIMetadata meta)
|
private (int removedIndex, int previousFullscreenIndex) Pop(UIMetadata meta)
|
||||||
{
|
{
|
||||||
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
|
var layer = _openUI[meta.MetaInfo.UILayer];
|
||||||
if (layer.HandleSet.Remove(meta.MetaInfo.RuntimeTypeHandle))
|
int previousFullscreenIndex = layer.LastFullscreenIndex;
|
||||||
|
if (layer.IndexMap.TryGetValue(meta.MetaInfo.RuntimeTypeHandle, out int index))
|
||||||
{
|
{
|
||||||
if (layer.IndexMap.TryGetValue(meta.MetaInfo.RuntimeTypeHandle, out int index))
|
layer.OrderList.RemoveAt(index);
|
||||||
{
|
layer.IndexMap.Remove(meta.MetaInfo.RuntimeTypeHandle);
|
||||||
layer.OrderList.RemoveAt(index);
|
|
||||||
layer.IndexMap.Remove(meta.MetaInfo.RuntimeTypeHandle);
|
|
||||||
|
|
||||||
// Update indices for all elements after the removed one
|
for (int i = index; i < layer.OrderList.Count; i++)
|
||||||
for (int i = index; i < layer.OrderList.Count; i++)
|
{
|
||||||
{
|
var item = layer.OrderList[i];
|
||||||
var m = layer.OrderList[i];
|
layer.IndexMap[item.MetaInfo.RuntimeTypeHandle] = i;
|
||||||
layer.IndexMap[m.MetaInfo.RuntimeTypeHandle] = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateFullscreenIndexAfterRemove(layer, meta, index);
|
||||||
|
return (index, previousFullscreenIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (-1, previousFullscreenIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -176,7 +183,7 @@ namespace AlicizaX.UI.Runtime
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void MoveToTop(UIMetadata meta)
|
private void MoveToTop(UIMetadata meta)
|
||||||
{
|
{
|
||||||
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
|
var layer = _openUI[meta.MetaInfo.UILayer];
|
||||||
int lastIdx = layer.OrderList.Count - 1;
|
int lastIdx = layer.OrderList.Count - 1;
|
||||||
|
|
||||||
if (!layer.IndexMap.TryGetValue(meta.MetaInfo.RuntimeTypeHandle, out int currentIdx))
|
if (!layer.IndexMap.TryGetValue(meta.MetaInfo.RuntimeTypeHandle, out int currentIdx))
|
||||||
@ -189,11 +196,12 @@ namespace AlicizaX.UI.Runtime
|
|||||||
|
|
||||||
for (int i = currentIdx; i < lastIdx; i++)
|
for (int i = currentIdx; i < lastIdx; i++)
|
||||||
{
|
{
|
||||||
var m = layer.OrderList[i];
|
var item = layer.OrderList[i];
|
||||||
layer.IndexMap[m.MetaInfo.RuntimeTypeHandle] = i;
|
layer.IndexMap[item.MetaInfo.RuntimeTypeHandle] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.IndexMap[meta.MetaInfo.RuntimeTypeHandle] = lastIdx;
|
layer.IndexMap[meta.MetaInfo.RuntimeTypeHandle] = lastIdx;
|
||||||
|
UpdateFullscreenIndexAfterMove(layer, meta, currentIdx, lastIdx);
|
||||||
|
|
||||||
SortWindowDepth(meta.MetaInfo.UILayer, currentIdx);
|
SortWindowDepth(meta.MetaInfo.UILayer, currentIdx);
|
||||||
}
|
}
|
||||||
@ -212,36 +220,40 @@ namespace AlicizaX.UI.Runtime
|
|||||||
await meta.View.InternalOpen(cancellationToken);
|
await meta.View.InternalOpen(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SortWindowVisible(int layer)
|
private void SortWindowVisible(int layer, int previousFullscreenIndex = int.MinValue)
|
||||||
{
|
{
|
||||||
var list = _openUI[layer].OrderList;
|
var layerData = _openUI[layer];
|
||||||
|
var list = layerData.OrderList;
|
||||||
int count = list.Count;
|
int count = list.Count;
|
||||||
|
|
||||||
int fullscreenIdx = -1;
|
int fullscreenIdx = layerData.LastFullscreenIndex;
|
||||||
for (int i = count - 1; i >= 0; i--)
|
if (fullscreenIdx >= count || (fullscreenIdx >= 0 && !IsDisplayFullscreen(list[fullscreenIdx])))
|
||||||
{
|
{
|
||||||
var meta = list[i];
|
fullscreenIdx = FindLastFullscreenIndex(list, count - 1);
|
||||||
if (meta.MetaInfo.FullScreen && UIStateMachine.IsDisplayActive(meta.State))
|
layerData.LastFullscreenIndex = fullscreenIdx;
|
||||||
{
|
|
||||||
fullscreenIdx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullscreenIdx == -1)
|
int oldFullscreenIndex = previousFullscreenIndex == int.MinValue ? fullscreenIdx : previousFullscreenIndex;
|
||||||
|
if (oldFullscreenIndex == fullscreenIdx)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
ApplyVisibilityRange(list, fullscreenIdx >= 0 ? fullscreenIdx : 0, count, fullscreenIdx);
|
||||||
{
|
return;
|
||||||
list[i].View.Visible = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (oldFullscreenIndex == -1 && fullscreenIdx == -1)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
ApplyVisibilityRange(list, 0, count, -1);
|
||||||
{
|
return;
|
||||||
list[i].View.Visible = (i >= fullscreenIdx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int start = oldFullscreenIndex < 0 || fullscreenIdx < 0
|
||||||
|
? 0
|
||||||
|
: Math.Min(oldFullscreenIndex, fullscreenIdx);
|
||||||
|
int endExclusive = oldFullscreenIndex < 0 || fullscreenIdx < 0
|
||||||
|
? count
|
||||||
|
: Math.Max(oldFullscreenIndex, fullscreenIdx) + 1;
|
||||||
|
|
||||||
|
ApplyVisibilityRange(list, start, endExclusive, fullscreenIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SortWindowDepth(int layer, int startIndex = 0)
|
private void SortWindowDepth(int layer, int startIndex = 0)
|
||||||
@ -259,5 +271,83 @@ namespace AlicizaX.UI.Runtime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsDisplayFullscreen(UIMetadata meta)
|
||||||
|
{
|
||||||
|
return meta.MetaInfo.FullScreen && UIStateMachine.IsDisplayActive(meta.State);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FindLastFullscreenIndex(List<UIMetadata> list, int startIndex)
|
||||||
|
{
|
||||||
|
for (int i = Math.Min(startIndex, list.Count - 1); i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (IsDisplayFullscreen(list[i]))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyVisibilityRange(List<UIMetadata> list, int startInclusive, int endExclusive, int fullscreenIdx)
|
||||||
|
{
|
||||||
|
if (startInclusive < 0)
|
||||||
|
{
|
||||||
|
startInclusive = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endExclusive > list.Count)
|
||||||
|
{
|
||||||
|
endExclusive = list.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showAll = fullscreenIdx < 0;
|
||||||
|
for (int i = startInclusive; i < endExclusive; i++)
|
||||||
|
{
|
||||||
|
list[i].View.Visible = showAll || i >= fullscreenIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateFullscreenIndexAfterRemove(LayerData layer, UIMetadata removedMeta, int removedIndex)
|
||||||
|
{
|
||||||
|
if (layer.OrderList.Count == 0)
|
||||||
|
{
|
||||||
|
layer.LastFullscreenIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removedMeta.MetaInfo.FullScreen && layer.LastFullscreenIndex == removedIndex)
|
||||||
|
{
|
||||||
|
layer.LastFullscreenIndex = FindLastFullscreenIndex(layer.OrderList, removedIndex - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removedIndex < layer.LastFullscreenIndex)
|
||||||
|
{
|
||||||
|
layer.LastFullscreenIndex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateFullscreenIndexAfterMove(LayerData layer, UIMetadata meta, int fromIndex, int toIndex)
|
||||||
|
{
|
||||||
|
if (layer.LastFullscreenIndex == fromIndex)
|
||||||
|
{
|
||||||
|
layer.LastFullscreenIndex = toIndex;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!meta.MetaInfo.FullScreen)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromIndex < layer.LastFullscreenIndex)
|
||||||
|
{
|
||||||
|
layer.LastFullscreenIndex--;
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.LastFullscreenIndex = Math.Max(layer.LastFullscreenIndex, toIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,10 @@ namespace AlicizaX.UI.Runtime
|
|||||||
|
|
||||||
Holder = holder;
|
Holder = holder;
|
||||||
_canvas = Holder.transform.GetComponent<Canvas>();
|
_canvas = Holder.transform.GetComponent<Canvas>();
|
||||||
_canvas.overrideSorting = true;
|
if (_canvas != null)
|
||||||
|
{
|
||||||
|
_canvas.overrideSorting = owner == null;
|
||||||
|
}
|
||||||
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
||||||
Holder.RectTransform.localPosition = Vector3.zero;
|
Holder.RectTransform.localPosition = Vector3.zero;
|
||||||
Holder.RectTransform.pivot = new Vector2(0.5f, 0.5f);
|
Holder.RectTransform.pivot = new Vector2(0.5f, 0.5f);
|
||||||
@ -96,7 +99,7 @@ namespace AlicizaX.UI.Runtime
|
|||||||
StartAsyncLoading(typeHandle, userDatas).Forget();
|
StartAsyncLoading(typeHandle, userDatas).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async UniTaskVoid StartAsyncLoading(RuntimeTypeHandle typeHandle, params System.Object[] userDatas)
|
private async UniTask StartAsyncLoading(RuntimeTypeHandle typeHandle, params System.Object[] userDatas)
|
||||||
{
|
{
|
||||||
_loadingFlags[typeHandle] = true;
|
_loadingFlags[typeHandle] = true;
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,10 @@ namespace AlicizaX.UI.Runtime
|
|||||||
Holder = holder;
|
Holder = holder;
|
||||||
_parent = owner;
|
_parent = owner;
|
||||||
_canvas = Holder.transform.GetComponent<Canvas>();
|
_canvas = Holder.transform.GetComponent<Canvas>();
|
||||||
|
if (_canvas != null)
|
||||||
|
{
|
||||||
|
_canvas.overrideSorting = false;
|
||||||
|
}
|
||||||
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
||||||
Depth = owner.Depth + 5;
|
Depth = owner.Depth + 5;
|
||||||
_state = UIState.Loaded;
|
_state = UIState.Loaded;
|
||||||
|
|||||||
@ -31,7 +31,10 @@ namespace AlicizaX.UI.Runtime
|
|||||||
throw new InvalidOperationException("UI already Created");
|
throw new InvalidOperationException("UI already Created");
|
||||||
Holder = holder;
|
Holder = holder;
|
||||||
_canvas = Holder.transform.GetComponent<Canvas>();
|
_canvas = Holder.transform.GetComponent<Canvas>();
|
||||||
_canvas.overrideSorting = true;
|
if (_canvas != null)
|
||||||
|
{
|
||||||
|
_canvas.overrideSorting = owner == null;
|
||||||
|
}
|
||||||
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
||||||
Holder.RectTransform.localPosition = Vector3.zero;
|
Holder.RectTransform.localPosition = Vector3.zero;
|
||||||
Holder.RectTransform.pivot = new Vector2(0.5f, 0.5f);
|
Holder.RectTransform.pivot = new Vector2(0.5f, 0.5f);
|
||||||
|
|||||||
@ -29,16 +29,17 @@ namespace AlicizaX.UI.Runtime
|
|||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_uiService = AppServices.GetOrCreateScope<AppScope>().Register(new UIService());
|
_uiService = AppServices.App.Register(new UIService());
|
||||||
if (uiRoot == null)
|
if (uiRoot == null)
|
||||||
{
|
{
|
||||||
throw new GameFrameworkException("UIRoot Prefab is invalid.");
|
throw new GameFrameworkException("UIRoot Prefab is invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObject obj = Instantiate(uiRoot, Vector3.zero, Quaternion.identity);
|
GameObject obj = Instantiate(uiRoot, Vector3.zero, Quaternion.identity);
|
||||||
obj.name = "------UI Root------";
|
obj.name = "------UI Root------";
|
||||||
_instanceRoot = obj.transform;
|
_instanceRoot = obj.transform;
|
||||||
Object.DontDestroyOnLoad(_instanceRoot);
|
Object.DontDestroyOnLoad(_instanceRoot);
|
||||||
_uiService.Initialize(_instanceRoot,_isOrthographic);
|
_uiService.Initialize(_instanceRoot, _isOrthographic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
@ -50,9 +51,9 @@ namespace AlicizaX.UI.Runtime
|
|||||||
#region 设置安全区域
|
#region 设置安全区域
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置屏幕安全区域(异形屏支持)。
|
/// 应用屏幕安全区域,适配刘海屏等显示区域。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="safeRect">安全区域</param>
|
/// <param name="safeRect">安全区域。</param>
|
||||||
public void ApplyScreenSafeRect(Rect safeRect)
|
public void ApplyScreenSafeRect(Rect safeRect)
|
||||||
{
|
{
|
||||||
CanvasScaler scaler = _uiService.UICanvasRoot.GetComponent<CanvasScaler>();
|
CanvasScaler scaler = _uiService.UICanvasRoot.GetComponent<CanvasScaler>();
|
||||||
@ -73,31 +74,31 @@ namespace AlicizaX.UI.Runtime
|
|||||||
float offsetMaxX = scaler.referenceResolution.x - width - posX;
|
float offsetMaxX = scaler.referenceResolution.x - width - posX;
|
||||||
float offsetMaxY = scaler.referenceResolution.y - height - posY;
|
float offsetMaxY = scaler.referenceResolution.y - height - posY;
|
||||||
|
|
||||||
// 注意:安全区坐标系的原点为左下角
|
// 注意:安全区域坐标系原点为左下角。
|
||||||
var rectTrans = _uiService.UICanvasRoot.transform as RectTransform;
|
var rectTrans = _uiService.UICanvasRoot.transform as RectTransform;
|
||||||
if (rectTrans != null)
|
if (rectTrans != null)
|
||||||
{
|
{
|
||||||
rectTrans.offsetMin = new Vector2(posX, posY); //锚框状态下的屏幕左下角偏移向量
|
rectTrans.offsetMin = new Vector2(posX, posY); // 锚点状态下的屏幕左下角偏移量。
|
||||||
rectTrans.offsetMax = new Vector2(-offsetMaxX, -offsetMaxY); //锚框状态下的屏幕右上角偏移向量
|
rectTrans.offsetMax = new Vector2(-offsetMaxX, -offsetMaxY); // 锚点状态下的屏幕右上角偏移量。
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 模拟IPhoneX异形屏
|
/// ģ<EFBFBD><EFBFBD>IPhoneX<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SimulateIPhoneXNotchScreen()
|
public void SimulateIPhoneXNotchScreen()
|
||||||
{
|
{
|
||||||
Rect rect;
|
Rect rect;
|
||||||
if (Screen.height > Screen.width)
|
if (Screen.height > Screen.width)
|
||||||
{
|
{
|
||||||
// 竖屏Portrait
|
// 竖屏
|
||||||
float deviceWidth = 1125;
|
float deviceWidth = 1125;
|
||||||
float deviceHeight = 2436;
|
float deviceHeight = 2436;
|
||||||
rect = new Rect(0f / deviceWidth, 102f / deviceHeight, 1125f / deviceWidth, 2202f / deviceHeight);
|
rect = new Rect(0f / deviceWidth, 102f / deviceHeight, 1125f / deviceWidth, 2202f / deviceHeight);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 横屏Landscape
|
// 横屏
|
||||||
float deviceWidth = 2436;
|
float deviceWidth = 2436;
|
||||||
float deviceHeight = 1125;
|
float deviceHeight = 1125;
|
||||||
rect = new Rect(132f / deviceWidth, 63f / deviceHeight, 2172f / deviceWidth, 1062f / deviceHeight);
|
rect = new Rect(132f / deviceWidth, 63f / deviceHeight, 2172f / deviceWidth, 1062f / deviceHeight);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user