优化Service 模块

This commit is contained in:
陈思海 2026-04-20 13:46:44 +08:00
parent c4c9a22fc4
commit 5849de3a42
38 changed files with 244 additions and 257 deletions

View File

@ -7,67 +7,90 @@ 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 HasScene => _world is { HasScene: true };
public static bool HasGameplay => _world != null && _world.HasGameplay; public static bool HasGameplay => _world is { HasGameplay: true };
public static ServiceWorld World internal static ServiceWorld EnsureWorld(int appScopeOrder = ServiceDomainOrder.App)
{
get
{
if (_world == null)
throw new InvalidOperationException("ServiceWorld has not been created yet.");
return _world;
}
}
public static ServiceScope App => World.App;
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;
} }
public static ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene) internal static ServiceWorld RequireWorld()
=> World.EnsureScene(order);
public static bool TryGetScene(out ServiceScope scope)
{ {
if (_world == null) { scope = null; return false; } if (_world == null)
return _world.TryGetScene(out scope); throw new InvalidOperationException("ServiceWorld has not been created yet.");
return _world;
} }
public static ServiceScope ResetScene(int order = ServiceDomainOrder.Scene) public static T RegisterApp<T>(T service, params Type[] extraContracts) where T : class, IService
=> World.ResetScene(order); => RequireWorld().App.Register(service, extraContracts);
public static bool DestroyScene() public static bool TryGetApp<T>(out T service) where T : class, IService
=> _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) { scope = null; return false; } if (_world == null)
return _world.TryGetGameplay(out scope); {
service = null;
return false;
} }
public static bool DestroyGameplay() return _world.App.TryGet(out service);
=> _world != null && _world.DestroyGameplay(); }
public static T RequireApp<T>() where T : class, IService
=> RequireWorld().App.Require<T>();
public static bool TryGet<T>(out T service) where T : class, IService public static bool TryGet<T>(out T service) where T : class, IService
{ {
if (_world == null) { service = null; return false; } if (_world == null)
{
service = null;
return false;
}
return _world.TryGet(out service); return _world.TryGet(out service);
} }
public static T Require<T>() where T : class, IService public static T Require<T>() where T : class, IService
=> World.Require<T>(); => RequireWorld().Require<T>();
internal static ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene)
=> RequireWorld().EnsureScene(order);
internal static bool TryGetScene(out ServiceScope scope)
{
if (_world == null)
{
scope = null;
return false;
}
return _world.TryGetScene(out scope);
}
internal static ServiceScope ResetScene(int order = ServiceDomainOrder.Scene)
=> RequireWorld().ResetScene(order);
internal static bool DestroyScene()
=> _world != null && _world.DestroyScene();
internal static ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay)
=> RequireWorld().EnsureGameplay(order);
internal static bool TryGetGameplay(out ServiceScope scope)
{
if (_world == null)
{
scope = null;
return false;
}
return _world.TryGetGameplay(out scope);
}
internal static bool DestroyGameplay()
=> _world != null && _world.DestroyGameplay();
public static void Shutdown() public static void Shutdown()
{ {

View File

@ -2,7 +2,5 @@ namespace AlicizaX
{ {
public interface IService public interface IService
{ {
void Initialize(ServiceContext context);
void Destroy();
} }
} }

View File

@ -0,0 +1,11 @@
using System;
namespace AlicizaX
{
public interface IServiceRegistry
{
T Register<T>(T service, params Type[] extraContracts) where T : class, IService;
bool TryGet<T>(out T service) where T : class, IService;
T Require<T>() where T : class, IService;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d190bfd76bea7644b922ec06f1be6b26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,16 +1,18 @@
namespace AlicizaX namespace AlicizaX
{ {
public abstract class ServiceBase : IService internal interface IServiceLifecycle
{ {
public ServiceContext Context { get; private set; } void Initialize(ServiceContext context);
void Destroy();
}
public bool IsInitialized { get; private set; } public abstract class ServiceBase : IService, IServiceLifecycle
{
protected ServiceContext Context { get; private set; }
protected ServiceWorld World => Context.World; protected bool IsInitialized { get; private set; }
protected ServiceScope Scope => Context.Scope; void IServiceLifecycle.Initialize(ServiceContext context)
void IService.Initialize(ServiceContext context)
{ {
if (IsInitialized) if (IsInitialized)
throw new System.InvalidOperationException($"{GetType().FullName} is already initialized."); throw new System.InvalidOperationException($"{GetType().FullName} is already initialized.");
@ -20,7 +22,7 @@ namespace AlicizaX
OnInitialize(); OnInitialize();
} }
void IService.Destroy() void IServiceLifecycle.Destroy()
{ {
if (!IsInitialized) return; if (!IsInitialized) return;

View File

@ -2,56 +2,48 @@ namespace AlicizaX
{ {
public readonly struct ServiceContext public readonly struct ServiceContext
{ {
public ServiceContext(ServiceWorld world, ServiceScope scope) internal ServiceContext(ServiceWorld world, ServiceScope scope)
{ {
World = world; World = world;
Scope = scope; Scope = scope;
} }
public ServiceWorld World { get; } internal ServiceWorld World { get; }
public ServiceScope Scope { get; } internal ServiceScope Scope { get; }
public ServiceScope App => World.App;
public ServiceScope AppScope => App;
public bool HasScene => World.HasScene; public bool HasScene => World.HasScene;
public bool HasGameplay => World.HasGameplay; 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);
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 EnsureScene(int order = ServiceDomainOrder.Scene) internal ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene)
=> World.EnsureScene(order); => World.EnsureScene(order);
public bool TryGetScene(out ServiceScope scope) internal bool TryGetScene(out ServiceScope scope)
=> World.TryGetScene(out scope); => World.TryGetScene(out scope);
public ServiceScope ResetScene(int order = ServiceDomainOrder.Scene) internal ServiceScope ResetScene(int order = ServiceDomainOrder.Scene)
=> World.ResetScene(order); => World.ResetScene(order);
public ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay) internal ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay)
=> World.EnsureGameplay(order); => World.EnsureGameplay(order);
public bool TryGetGameplay(out ServiceScope scope) internal bool TryGetGameplay(out ServiceScope scope)
=> World.TryGetGameplay(out scope); => World.TryGetGameplay(out scope);
public T RequireApp<T>() where T : class, IService public T RequireApp<T>() where T : class, IService
=> App.Require<T>(); => World.App.Require<T>();
public T RequireScene<T>() where T : class, IService public T RequireScene<T>() where T : class, IService
=> Scene.Require<T>(); => World.Scene.Require<T>();
public T RequireGameplay<T>() where T : class, IService public T RequireGameplay<T>() where T : class, IService
=> Gameplay.Require<T>(); => World.Gameplay.Require<T>();
} }
} }

View File

@ -8,11 +8,13 @@ namespace AlicizaX
private static readonly HashSet<Type> ExcludedContracts = new HashSet<Type> private static readonly HashSet<Type> ExcludedContracts = new HashSet<Type>
{ {
typeof(IService), typeof(IService),
typeof(IMonoService),
typeof(IServiceTickable), typeof(IServiceTickable),
typeof(IServiceLateTickable), typeof(IServiceLateTickable),
typeof(IServiceFixedTickable), typeof(IServiceFixedTickable),
typeof(IServiceGizmoDrawable), typeof(IServiceGizmoDrawable),
typeof(IServiceOrder), typeof(IServiceOrder),
typeof(IServiceLifecycle),
}; };
// Cache for the common no-extraContracts path — contracts per concrete type never change. // Cache for the common no-extraContracts path — contracts per concrete type never change.

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace AlicizaX namespace AlicizaX
{ {
public sealed class ServiceScope : IDisposable internal sealed class ServiceScope : IDisposable, IServiceRegistry
{ {
private readonly Dictionary<Type, IService> _servicesByContract = new Dictionary<Type, IService>(); private readonly Dictionary<Type, IService> _servicesByContract = new Dictionary<Type, IService>();
private readonly Dictionary<IService, List<Type>> _contractsByService = new Dictionary<IService, List<Type>>(ReferenceComparer<IService>.Instance); private readonly Dictionary<IService, List<Type>> _contractsByService = new Dictionary<IService, List<Type>>(ReferenceComparer<IService>.Instance);
@ -31,13 +31,13 @@ namespace AlicizaX
Order = order; Order = order;
} }
public ServiceWorld World { get; } internal ServiceWorld World { get; }
public string Name { get; } public string Name { get; }
public int Order { get; } internal int Order { get; }
public bool IsDisposed { get; private set; } internal bool IsDisposed { get; private set; }
public T Register<T>(T service, params Type[] extraContracts) public T Register<T>(T service, params Type[] extraContracts)
where T : class, IService where T : class, IService
@ -47,6 +47,9 @@ namespace AlicizaX
if (service == null) if (service == null)
throw new ArgumentNullException(nameof(service)); throw new ArgumentNullException(nameof(service));
if (service is not IServiceLifecycle lifecycle)
throw new InvalidOperationException($"Service {service.GetType().FullName} must implement {nameof(IServiceLifecycle)}.");
ValidateService(service); ValidateService(service);
if (_contractsByService.ContainsKey(service)) if (_contractsByService.ContainsKey(service))
@ -70,7 +73,7 @@ namespace AlicizaX
try try
{ {
service.Initialize(new ServiceContext(World, this)); lifecycle.Initialize(new ServiceContext(World, this));
AddToLifecycleLists(service); AddToLifecycleLists(service);
} }
catch catch
@ -94,9 +97,12 @@ namespace AlicizaX
if (service == null || !_contractsByService.ContainsKey(service)) if (service == null || !_contractsByService.ContainsKey(service))
return false; return false;
if (service is not IServiceLifecycle lifecycle)
throw new InvalidOperationException($"Service {service.GetType().FullName} must implement {nameof(IServiceLifecycle)}.");
RemoveFromLifecycleLists(service); RemoveFromLifecycleLists(service);
RemoveBindings(service); RemoveBindings(service);
service.Destroy(); lifecycle.Destroy();
return true; return true;
} }
@ -155,9 +161,11 @@ namespace AlicizaX
{ {
var service = snapshot[i]; var service = snapshot[i];
if (!_contractsByService.ContainsKey(service)) continue; if (!_contractsByService.ContainsKey(service)) continue;
if (service is not IServiceLifecycle lifecycle)
throw new InvalidOperationException($"Service {service.GetType().FullName} must implement {nameof(IServiceLifecycle)}.");
RemoveFromLifecycleLists(service); RemoveFromLifecycleLists(service);
RemoveContractBindings(service); // skip _registrationOrder.Remove — we clear below RemoveContractBindings(service); // skip _registrationOrder.Remove — we clear below
service.Destroy(); lifecycle.Destroy();
} }
_registrationOrder.Clear(); _registrationOrder.Clear();

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace AlicizaX namespace AlicizaX
{ {
public sealed class ServiceWorld : IDisposable internal sealed class ServiceWorld : IDisposable
{ {
private readonly List<ServiceScope> _scopes = new List<ServiceScope>(); private readonly List<ServiceScope> _scopes = new List<ServiceScope>();
private readonly Dictionary<Type, ServiceScope> _scopesByType = new Dictionary<Type, ServiceScope>(); private readonly Dictionary<Type, ServiceScope> _scopesByType = new Dictionary<Type, ServiceScope>();
@ -13,20 +13,20 @@ namespace AlicizaX
private ServiceScope _sceneScope; private ServiceScope _sceneScope;
private ServiceScope _gameplayScope; private ServiceScope _gameplayScope;
public ServiceWorld(int appScopeOrder = ServiceDomainOrder.App) internal ServiceWorld(int appScopeOrder = ServiceDomainOrder.App)
{ {
App = CreateScopeInternal(typeof(AppScope), nameof(AppScope), appScopeOrder); App = CreateScopeInternal(typeof(AppScope), nameof(AppScope), appScopeOrder);
} }
public ServiceScope App { get; } internal ServiceScope App { get; }
public ServiceScope AppScope => App; internal ServiceScope AppScope => App;
public bool HasScene => _sceneScope != null && !_sceneScope.IsDisposed; internal bool HasScene => _sceneScope != null && !_sceneScope.IsDisposed;
public bool HasGameplay => _gameplayScope != null && !_gameplayScope.IsDisposed; internal bool HasGameplay => _gameplayScope != null && !_gameplayScope.IsDisposed;
public ServiceScope Scene internal ServiceScope Scene
{ {
get get
{ {
@ -36,7 +36,7 @@ namespace AlicizaX
} }
} }
public ServiceScope Gameplay internal ServiceScope Gameplay
{ {
get get
{ {
@ -46,24 +46,24 @@ namespace AlicizaX
} }
} }
public ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene) internal ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene)
=> _sceneScope is { IsDisposed: false } => _sceneScope is { IsDisposed: false }
? _sceneScope ? _sceneScope
: _sceneScope = CreateScopeInternal(typeof(SceneScope), nameof(SceneScope), order); : _sceneScope = CreateScopeInternal(typeof(SceneScope), nameof(SceneScope), order);
public bool TryGetScene(out ServiceScope scope) internal bool TryGetScene(out ServiceScope scope)
{ {
scope = HasScene ? _sceneScope : null; scope = HasScene ? _sceneScope : null;
return scope != null; return scope != null;
} }
public ServiceScope ResetScene(int order = ServiceDomainOrder.Scene) internal ServiceScope ResetScene(int order = ServiceDomainOrder.Scene)
{ {
DestroyScene(); DestroyScene();
return EnsureScene(order); return EnsureScene(order);
} }
public bool DestroyScene() internal bool DestroyScene()
{ {
if (!HasScene) if (!HasScene)
return false; return false;
@ -73,18 +73,18 @@ namespace AlicizaX
return DestroyScope(scope, typeof(SceneScope)); return DestroyScope(scope, typeof(SceneScope));
} }
public ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay) internal ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay)
=> _gameplayScope is { IsDisposed: false } => _gameplayScope is { IsDisposed: false }
? _gameplayScope ? _gameplayScope
: _gameplayScope = CreateScopeInternal(typeof(GameplayScope), nameof(GameplayScope), order); : _gameplayScope = CreateScopeInternal(typeof(GameplayScope), nameof(GameplayScope), order);
public bool TryGetGameplay(out ServiceScope scope) internal bool TryGetGameplay(out ServiceScope scope)
{ {
scope = HasGameplay ? _gameplayScope : null; scope = HasGameplay ? _gameplayScope : null;
return scope != null; return scope != null;
} }
public bool DestroyGameplay() internal bool DestroyGameplay()
{ {
if (!HasGameplay) if (!HasGameplay)
return false; return false;
@ -94,10 +94,10 @@ namespace AlicizaX
return DestroyScope(scope, typeof(GameplayScope)); return DestroyScope(scope, typeof(GameplayScope));
} }
public bool TryGet<T>(out T service) where T : class, IService internal bool TryGet<T>(out T service) where T : class, IService
=> TryGet(null, out service); => TryGet(null, out service);
public bool TryGet<T>(ServiceScope preferredScope, out T service) where T : class, IService internal bool TryGet<T>(ServiceScope preferredScope, out T service) where T : class, IService
{ {
if (preferredScope != null && !preferredScope.IsDisposed && preferredScope.TryGet(out service)) if (preferredScope != null && !preferredScope.IsDisposed && preferredScope.TryGet(out service))
return true; return true;
@ -114,33 +114,33 @@ namespace AlicizaX
return false; return false;
} }
public T Require<T>() where T : class, IService => Require<T>(null); internal T Require<T>() where T : class, IService => Require<T>(null);
public T Require<T>(ServiceScope preferredScope) where T : class, IService internal T Require<T>(ServiceScope preferredScope) where T : class, IService
{ {
if (TryGet(preferredScope, out T service)) return service; if (TryGet(preferredScope, out T service)) return service;
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.");
} }
public void Tick(float deltaTime) internal void Tick(float deltaTime)
{ {
var snapshot = GetScopeSnapshot(); var snapshot = GetScopeSnapshot();
for (var i = 0; i < snapshot.Length; i++) snapshot[i].Tick(deltaTime); for (var i = 0; i < snapshot.Length; i++) snapshot[i].Tick(deltaTime);
} }
public void LateTick(float deltaTime) internal void LateTick(float deltaTime)
{ {
var snapshot = GetScopeSnapshot(); var snapshot = GetScopeSnapshot();
for (var i = 0; i < snapshot.Length; i++) snapshot[i].LateTick(deltaTime); for (var i = 0; i < snapshot.Length; i++) snapshot[i].LateTick(deltaTime);
} }
public void FixedTick(float fixedDeltaTime) internal void FixedTick(float fixedDeltaTime)
{ {
var snapshot = GetScopeSnapshot(); var snapshot = GetScopeSnapshot();
for (var i = 0; i < snapshot.Length; i++) snapshot[i].FixedTick(fixedDeltaTime); for (var i = 0; i < snapshot.Length; i++) snapshot[i].FixedTick(fixedDeltaTime);
} }
public void DrawGizmos() internal void DrawGizmos()
{ {
var snapshot = GetScopeSnapshot(); var snapshot = GetScopeSnapshot();
for (var i = 0; i < snapshot.Length; i++) snapshot[i].DrawGizmos(); for (var i = 0; i < snapshot.Length; i++) snapshot[i].DrawGizmos();

View File

@ -37,22 +37,22 @@ namespace AlicizaX
protected virtual void Update() protected virtual void Update()
{ {
if (AppServices.HasWorld) AppServices.World.Tick(Time.deltaTime); if (AppServices.HasWorld) AppServices.RequireWorld().Tick(Time.deltaTime);
} }
protected virtual void LateUpdate() protected virtual void LateUpdate()
{ {
if (AppServices.HasWorld) AppServices.World.LateTick(Time.deltaTime); if (AppServices.HasWorld) AppServices.RequireWorld().LateTick(Time.deltaTime);
} }
protected virtual void FixedUpdate() protected virtual void FixedUpdate()
{ {
if (AppServices.HasWorld) AppServices.World.FixedTick(Time.fixedDeltaTime); if (AppServices.HasWorld) AppServices.RequireWorld().FixedTick(Time.fixedDeltaTime);
} }
protected virtual void OnDrawGizmos() protected virtual void OnDrawGizmos()
{ {
if (AppServices.HasWorld) AppServices.World.DrawGizmos(); if (AppServices.HasWorld) AppServices.RequireWorld().DrawGizmos();
} }
protected virtual async void OnDestroy() protected virtual async void OnDestroy()
@ -68,6 +68,6 @@ namespace AlicizaX
} }
protected virtual void RegisterAppServices(ServiceScope appScope) { } protected virtual void RegisterAppServices(IServiceRegistry appServices) { }
} }
} }

View File

@ -2,17 +2,13 @@ using UnityEngine;
namespace AlicizaX namespace AlicizaX
{ {
public abstract class MonoServiceBehaviour : MonoBehaviour, IMonoService public abstract class MonoServiceBehaviour : MonoBehaviour, IMonoService, IServiceLifecycle
{ {
public ServiceContext Context { get; private set; } protected ServiceContext Context { get; private set; }
public bool IsInitialized { get; private set; } protected bool IsInitialized { get; private set; }
protected ServiceWorld World => Context.World; void IServiceLifecycle.Initialize(ServiceContext context)
protected ServiceScope Scope => Context.Scope;
void IService.Initialize(ServiceContext context)
{ {
if (IsInitialized) if (IsInitialized)
throw new System.InvalidOperationException($"{GetType().FullName} is already initialized."); throw new System.InvalidOperationException($"{GetType().FullName} is already initialized.");
@ -22,7 +18,7 @@ namespace AlicizaX
OnInitialize(); OnInitialize();
} }
void IService.Destroy() void IServiceLifecycle.Destroy()
{ {
if (!IsInitialized) return; if (!IsInitialized) return;
@ -74,7 +70,7 @@ namespace AlicizaX
private static ServiceScope ResolveOrCreateScope() private static ServiceScope ResolveOrCreateScope()
{ {
if (typeof(TScope) == typeof(AppScope)) if (typeof(TScope) == typeof(AppScope))
return AppServices.App; return AppServices.RequireWorld().App;
if (typeof(TScope) == typeof(SceneScope)) if (typeof(TScope) == typeof(SceneScope))
return AppServices.EnsureScene(); return AppServices.EnsureScene();
@ -89,7 +85,7 @@ namespace AlicizaX
{ {
if (typeof(TScope) == typeof(AppScope)) if (typeof(TScope) == typeof(AppScope))
{ {
scope = AppServices.App; scope = AppServices.RequireWorld().App;
return true; return true;
} }

View File

@ -42,7 +42,7 @@ namespace AlicizaX.ObjectPool
/// <summary> /// <summary>
/// 对象池管理器。 /// 对象池管理器。
/// </summary> /// </summary>
public interface IObjectPoolService : IService, IServiceTickable public interface IObjectPoolService : IService
{ {
int Count { get; } int Count { get; }

View File

@ -4,14 +4,14 @@ 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.App.Register(new ObjectPoolService()); _mObjectPoolService = AppServices.RegisterApp(new ObjectPoolService());
} }
private void OnDestroy() private void OnDestroy()
@ -29,10 +29,10 @@ 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);

View File

@ -9,7 +9,7 @@ namespace AlicizaX.ObjectPool
/// 对象池管理器。 /// 对象池管理器。
/// </summary> /// </summary>
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
internal sealed partial class ObjectPoolService : ServiceBase, IObjectPoolService internal sealed partial class ObjectPoolService : ServiceBase, IObjectPoolService, IServiceTickable
{ {
private const int DefaultCapacity = int.MaxValue; private const int DefaultCapacity = int.MaxValue;
private const float DefaultExpireTime = float.MaxValue; private const float DefaultExpireTime = float.MaxValue;

View File

@ -77,7 +77,7 @@ namespace AlicizaX
catch (UnityWebRequestException e) catch (UnityWebRequestException e)
{ {
HandleRequestError(request, url); HandleRequestError(request, url);
return string.Empty; return e.Message;
} }
} }

View File

@ -81,9 +81,9 @@ namespace AlicizaX
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false; UnityEditor.EditorApplication.isPlaying = false;
return; #else
#endif
Application.Quit(); Application.Quit();
#endif
} }
#if UNITY_IOS #if UNITY_IOS
@ -98,9 +98,7 @@ namespace AlicizaX
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
Application.OpenURL(url); Application.OpenURL(url);
return; #elif UNITY_IOS
#endif
#if UNITY_IOS
open_url(url); open_url(url);
#else #else
Application.OpenURL(url); Application.OpenURL(url);

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections; using System.Collections;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
@ -286,7 +286,7 @@ namespace AlicizaX
return; return;
} }
_loopService = AppServices.App.Register(new UtilityLoopService()); _loopService = AppServices.RegisterApp(new UtilityLoopService());
} }
private static UtilityLoopService EnsureLoopService() private static UtilityLoopService EnsureLoopService()

View File

@ -5,9 +5,9 @@ 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.App.Register(new AudioService()); _audioService = AppServices.RegisterApp(new AudioService());
} }
/// <summary> /// <summary>
/// 初始化音频模块。 /// 初始化音频模块。
/// </summary> /// </summary>
void Start() void Start()
{ {

View File

@ -12,7 +12,7 @@ using AudioType = AlicizaX.Audio.Runtime.AudioType;
namespace AlicizaX.Audio.Runtime namespace AlicizaX.Audio.Runtime
{ {
internal class AudioService : ServiceBase, IAudioService internal class AudioService : ServiceBase, IAudioService, IServiceTickable
{ {
public const string MUSIC_VOLUME_NAME = "MusicVolume"; public const string MUSIC_VOLUME_NAME = "MusicVolume";
public const string UI_SOUND_VOLUME_NAME = "UISoundVolume"; public const string UI_SOUND_VOLUME_NAME = "UISoundVolume";

View File

@ -6,7 +6,7 @@ using YooAsset;
namespace AlicizaX.Audio.Runtime namespace AlicizaX.Audio.Runtime
{ {
public interface IAudioService:IService, IServiceTickable public interface IAudioService : IService
{ {
/// <summary> /// <summary>
/// 总音量控制。 /// 总音量控制。

View File

@ -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>? /// 榛樿璋冭瘯鍣ㄧ獥鍙eぇ灏忋€?
/// </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>? /// 榛樿璋冭瘯鍣ㄧ獥鍙g缉鏀炬瘮渚嬨€?
/// </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.App.Register(new DebuggerService()); _mDebuggerService = AppServices.RegisterApp(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>? /// 娉ㄥ唽璋冭瘯鍣ㄧ獥鍙c€?
/// </summary> /// </summary>
/// <param name="path"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param> /// <param name="path">璋冭瘯鍣ㄧ獥鍙h矾寰勩€?/param>
/// <param name="debuggerWindow"><EFBFBD><EFBFBD>𣬚<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/param> /// <param name="debuggerWindow">瑕佹敞鍐岀殑璋冭瘯鍣ㄧ獥鍙c€?/param>
/// <param name="args"><EFBFBD><EFBFBD><EFBFBD>𤥁<EFBFBD>霂訫膥蝒堒藁<EFBFBD><EFBFBD><EFBFBD>?/param> /// <param name="args">鍒濆鍖栬皟璇曞櫒绐楀彛鍙傛暟銆?/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>? /// 瑙i櫎娉ㄥ唽璋冭瘯鍣ㄧ獥鍙c€?
/// </summary> /// </summary>
/// <param name="path"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param> /// <param name="path">璋冭瘯鍣ㄧ獥鍙h矾寰勩€?/param>
/// <returns><EFBFBD>臬炏閫<EFBFBD>膄瘜典<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/returns> /// <returns>鏄惁瑙i櫎娉ㄥ唽璋冭瘯鍣ㄧ獥鍙f垚鍔熴€?/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>? /// 鑾峰彇璋冭瘯鍣ㄧ獥鍙c€?
/// </summary> /// </summary>
/// <param name="path"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param> /// <param name="path">璋冭瘯鍣ㄧ獥鍙h矾寰勩€?/param>
/// <returns><EFBFBD><EFBFBD>𣇉<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/returns> /// <returns>瑕佽幏鍙栫殑璋冭瘯鍣ㄧ獥鍙c€?/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>? /// 閫変腑璋冭瘯鍣ㄧ獥鍙c€?
/// </summary> /// </summary>
/// <param name="path"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param> /// <param name="path">璋冭瘯鍣ㄧ獥鍙h矾寰勩€?/param>
/// <returns><EFBFBD>臬炏<EFBFBD>𣂼<EFBFBD><EFBFBD>劐葉靚<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/returns> /// <returns>鏄惁鎴愬姛閫変腑璋冭瘯鍣ㄧ獥鍙c€?/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>? /// 杩樺師璋冭瘯鍣ㄧ獥鍙e竷灞€銆?
/// </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"><EFBFBD><EFBFBD>𣇉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/param> /// <param name="results">瑕佽幏鍙栫殑鏃ュ織銆?/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"><EFBFBD><EFBFBD>𣇉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/param> /// <param name="results">瑕佽幏鍙栫殑鏃ュ織銆?/param>
/// <param name="count"><EFBFBD><EFBFBD>𡝗<EFBFBD>餈烐𠯫敹㛖<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/param> /// <param name="count">瑕佽幏鍙栨渶杩戞棩蹇楃殑鏁伴噺銆?/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);

View File

@ -7,7 +7,7 @@ namespace AlicizaX.Debugger.Runtime
/// 调试器管理器。 /// 调试器管理器。
/// </summary> /// </summary>
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
internal sealed partial class DebuggerService : ServiceBase, IDebuggerService internal sealed partial class DebuggerService : ServiceBase, IDebuggerService, IServiceTickable
{ {
private readonly DebuggerWindowGroup m_DebuggerWindowRoot; private readonly DebuggerWindowGroup m_DebuggerWindowRoot;
private bool m_ActiveWindow; private bool m_ActiveWindow;

View File

@ -6,7 +6,7 @@ using AlicizaX;
namespace AlicizaX.Debugger.Runtime namespace AlicizaX.Debugger.Runtime
{ {
/// <summary>调试器管理器接口。</summary> /// <summary>调试器管理器接口。</summary>
public interface IDebuggerService:IService, IServiceTickable public interface IDebuggerService : IService
{ {
/// <summary>获取或设置调试器窗口是否激活。</summary> /// <summary>获取或设置调试器窗口是否激活。</summary>
bool ActiveWindow { get; set; } bool ActiveWindow { get; set; }

View File

@ -23,7 +23,7 @@ public static partial class GameApp
{ {
if (_audio == null) if (_audio == null)
{ {
_audio = AppServices.App.Require<IAudioService>(); _audio = AppServices.RequireApp<IAudioService>();
} }
return _audio; return _audio;
@ -42,7 +42,7 @@ public static partial class GameApp
{ {
if (_localization == null) if (_localization == null)
{ {
_localization = AppServices.App.Require<ILocalizationService>(); _localization = AppServices.RequireApp<ILocalizationService>();
} }
return _localization; return _localization;
@ -60,7 +60,7 @@ public static partial class GameApp
{ {
if (_objectPool == null) if (_objectPool == null)
{ {
_objectPool = AppServices.App.Require<IObjectPoolService>(); _objectPool = AppServices.RequireApp<IObjectPoolService>();
} }
return _objectPool; return _objectPool;
@ -79,7 +79,7 @@ public static partial class GameApp
{ {
if (_procedure == null) if (_procedure == null)
{ {
_procedure = AppServices.App.Require<IProcedureService>(); _procedure = AppServices.RequireApp<IProcedureService>();
} }
return _procedure; return _procedure;
@ -98,7 +98,7 @@ public static partial class GameApp
{ {
if (_resource == null) if (_resource == null)
{ {
_resource = AppServices.App.Require<IResourceService>(); _resource = AppServices.RequireApp<IResourceService>();
} }
return _resource; return _resource;
@ -116,7 +116,7 @@ public static partial class GameApp
{ {
if (_scene == null) if (_scene == null)
{ {
_scene = AppServices.App.Require<ISceneService>(); _scene = AppServices.RequireApp<ISceneService>();
} }
return _scene; return _scene;
@ -134,7 +134,7 @@ public static partial class GameApp
{ {
if (_timer == null) if (_timer == null)
{ {
_timer = AppServices.App.Require<ITimerService>(); _timer = AppServices.RequireApp<ITimerService>();
} }
return _timer; return _timer;
@ -153,7 +153,7 @@ public static partial class GameApp
{ {
if (_ui == null) if (_ui == null)
{ {
_ui = AppServices.App.Require<IUIService>(); _ui = AppServices.RequireApp<IUIService>();
} }
return _ui; return _ui;

View File

@ -53,9 +53,9 @@ namespace AlicizaX.Localization.Runtime
private void Start() private void Start()
{ {
if (!AppServices.App.TryGet<ILocalizationService>(out _mLocalizationService)) if (!AppServices.TryGetApp<ILocalizationService>(out _mLocalizationService))
{ {
_mLocalizationService = AppServices.App.Register(new LocalizationService()); _mLocalizationService = AppServices.RegisterApp(new LocalizationService());
} }
if (_mLocalizationService == null) if (_mLocalizationService == null)

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace AlicizaX namespace AlicizaX
{ {
public interface IProcedureService : IService, IServiceTickable public interface IProcedureService : IService
{ {
Type CurrentProcedureType { get; } Type CurrentProcedureType { get; }
void InitializeProcedure(IEnumerable<IProcedure> availableProcedures, Type defaultProcedureType); void InitializeProcedure(IEnumerable<IProcedure> availableProcedures, Type defaultProcedureType);

View File

@ -8,7 +8,7 @@ namespace AlicizaX
{ {
private void Awake() private void Awake()
{ {
AppServices.App.Register(new ProcedureService()); AppServices.RegisterApp(new ProcedureService());
} }
} }
} }

View File

@ -4,7 +4,7 @@ using UnityEngine;
namespace AlicizaX namespace AlicizaX
{ {
internal class ProcedureService : ServiceBase, IProcedureService internal class ProcedureService : ServiceBase, IProcedureService, IServiceTickable
{ {
private readonly Dictionary<Type, IProcedure> _procedures = new Dictionary<Type, IProcedure>(); private readonly Dictionary<Type, IProcedure> _procedures = new Dictionary<Type, IProcedure>();
private IProcedure _currentProcedure; private IProcedure _currentProcedure;

View File

@ -6,9 +6,6 @@ using YooAsset;
namespace AlicizaX.Resource.Runtime namespace AlicizaX.Resource.Runtime
{ {
/// <summary>
/// 资源组件<E7BB84>?
/// </summary>
[DisallowMultipleComponent] [DisallowMultipleComponent]
public class ResourceComponent : MonoBehaviour public class ResourceComponent : MonoBehaviour
{ {
@ -40,26 +37,14 @@ namespace AlicizaX.Resource.Runtime
[SerializeField] private string decryptionServices = ""; [SerializeField] private string decryptionServices = "";
/// <summary>
/// 自动释放资源引用计数<E8AEA1>?的资源包
/// </summary>
[SerializeField] public bool autoUnloadBundleWhenUnused = false; [SerializeField] public bool autoUnloadBundleWhenUnused = false;
[SerializeField] private EPlayMode _playMode = EPlayMode.EditorSimulateMode; [SerializeField] private EPlayMode _playMode = EPlayMode.EditorSimulateMode;
/// <summary>
/// 当前最新的包裹版本<E78988>?
/// </summary>
public string PackageVersion { set; get; } public string PackageVersion { set; get; }
/// <summary>
/// 资源包名称<E5908D>?
/// </summary>
[SerializeField] private string packageName = "DefaultPackage"; [SerializeField] private string packageName = "DefaultPackage";
/// <summary>
/// 资源包名称<E5908D>?
/// </summary>
public string PackageName public string PackageName
{ {
get => packageName; get => packageName;
@ -67,16 +52,11 @@ namespace AlicizaX.Resource.Runtime
} }
/// <summary>
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)
/// </summary>
[SerializeField] public long milliseconds = 30; [SerializeField] public long milliseconds = 30;
public int downloadingMaxNum = 10; public int downloadingMaxNum = 10;
/// <summary>
/// 获取或设置同时最大下载数目<E695B0>?
/// </summary>
public int DownloadingMaxNum public int DownloadingMaxNum
{ {
get => downloadingMaxNum; get => downloadingMaxNum;
@ -91,46 +71,31 @@ namespace AlicizaX.Resource.Runtime
set => failedTryAgain = value; set => failedTryAgain = value;
} }
/// <summary>
/// 获取当前资源适用的游戏版本号<E69CAC>?
/// </summary>
public string ApplicableGameVersion => _resourceService.ApplicableGameVersion; public string ApplicableGameVersion => _resourceService.ApplicableGameVersion;
/// <summary>
/// 获取当前内部资源版本号<E69CAC>?
/// </summary>
public int InternalResourceVersion => _resourceService.InternalResourceVersion; public int InternalResourceVersion => _resourceService.InternalResourceVersion;
/// <summary>
/// 获取或设置无用资源释放的最小间隔时间以秒为单位<E58D95>?
/// </summary>
public float MinUnloadUnusedAssetsInterval public float MinUnloadUnusedAssetsInterval
{ {
get => minUnloadUnusedAssetsInterval; get => minUnloadUnusedAssetsInterval;
set => minUnloadUnusedAssetsInterval = value; set => minUnloadUnusedAssetsInterval = value;
} }
/// <summary>
/// 获取或设置无用资源释放的最大间隔时间以秒为单位<E58D95>?
/// </summary>
public float MaxUnloadUnusedAssetsInterval public float MaxUnloadUnusedAssetsInterval
{ {
get => maxUnloadUnusedAssetsInterval; get => maxUnloadUnusedAssetsInterval;
set => maxUnloadUnusedAssetsInterval = value; set => maxUnloadUnusedAssetsInterval = value;
} }
/// <summary>
/// 使用系统释放无用资源策略<E7AD96>?
/// </summary>
public bool UseSystemUnloadUnusedAssets public bool UseSystemUnloadUnusedAssets
{ {
get => useSystemUnloadUnusedAssets; get => useSystemUnloadUnusedAssets;
set => useSystemUnloadUnusedAssets = value; set => useSystemUnloadUnusedAssets = value;
} }
/// <summary>
/// 获取无用资源释放的等待时长以秒为单位<E58D95>?
/// </summary>
public float LastUnloadUnusedAssetsOperationElapseSeconds => _lastUnloadUnusedAssetsOperationElapseSeconds; public float LastUnloadUnusedAssetsOperationElapseSeconds => _lastUnloadUnusedAssetsOperationElapseSeconds;
[SerializeField] private float assetAutoReleaseInterval = 60f; [SerializeField] private float assetAutoReleaseInterval = 60f;
@ -141,36 +106,28 @@ namespace AlicizaX.Resource.Runtime
[SerializeField] private int assetPriority = 0; [SerializeField] private int assetPriority = 0;
/// <summary>
/// 获取或设置资源对象池自动释放可释放对象的间隔秒数<E7A792>?
/// </summary>
public float AssetAutoReleaseInterval public float AssetAutoReleaseInterval
{ {
get => _resourceService.AssetAutoReleaseInterval; get => _resourceService.AssetAutoReleaseInterval;
set => _resourceService.AssetAutoReleaseInterval = assetAutoReleaseInterval = value; set => _resourceService.AssetAutoReleaseInterval = assetAutoReleaseInterval = value;
} }
/// <summary>
/// 获取或设置资源对象池的容量<E5AEB9>?
/// </summary>
public int AssetCapacity public int AssetCapacity
{ {
get => _resourceService.AssetCapacity; get => _resourceService.AssetCapacity;
set => _resourceService.AssetCapacity = assetCapacity = value; set => _resourceService.AssetCapacity = assetCapacity = value;
} }
/// <summary>
/// 获取或设置资源对象池对象过期秒数<E7A792>?
/// </summary>
public float AssetExpireTime public float AssetExpireTime
{ {
get => _resourceService.AssetExpireTime; get => _resourceService.AssetExpireTime;
set => _resourceService.AssetExpireTime = assetExpireTime = value; set => _resourceService.AssetExpireTime = assetExpireTime = value;
} }
/// <summary>
/// 获取或设置资源对象池的优先级<E58588>?
/// </summary>
public int AssetPriority public int AssetPriority
{ {
get => _resourceService.AssetPriority; get => _resourceService.AssetPriority;
@ -191,7 +148,7 @@ namespace AlicizaX.Resource.Runtime
private void Awake() private void Awake()
{ {
_resourceService = AppServices.App.Register(new ResourceService()); _resourceService = AppServices.RegisterApp(new ResourceService());
Application.lowMemory += OnLowMemory; Application.lowMemory += OnLowMemory;
} }
@ -216,7 +173,7 @@ namespace AlicizaX.Resource.Runtime
_resourceService.AssetExpireTime = assetExpireTime; _resourceService.AssetExpireTime = assetExpireTime;
_resourceService.AssetPriority = assetPriority; _resourceService.AssetPriority = assetPriority;
_resourceService.SetForceUnloadUnusedAssetsAction(ForceUnloadUnusedAssets); _resourceService.SetForceUnloadUnusedAssetsAction(ForceUnloadUnusedAssets);
Log.Info($"ResourceModule Run Mode{_playMode}"); Log.Info($"ResourceModule Run Mode {_playMode}");
} }
private void OnApplicationQuit() private void OnApplicationQuit()
@ -224,12 +181,8 @@ namespace AlicizaX.Resource.Runtime
Application.lowMemory -= OnLowMemory; Application.lowMemory -= OnLowMemory;
} }
#region #region
/// <summary>
/// 强制执行释放未被使用的资源<E8B584>?
/// </summary>
/// <param name="performGCCollect">是否使用垃圾回收<E59B9E>?/param>
public void ForceUnloadUnusedAssets(bool performGCCollect) public void ForceUnloadUnusedAssets(bool performGCCollect)
{ {
_forceUnloadUnusedAssets = true; _forceUnloadUnusedAssets = true;

View File

@ -37,12 +37,6 @@ namespace AlicizaX.Resource.Runtime
/// </summary> /// </summary>
public long Milliseconds { get; set; } = 30; public long Milliseconds { get; set; } = 30;
public int Priority
{
get => 2;
}
private string _applicableGameVersion; private string _applicableGameVersion;
private int _internalResourceVersion; private int _internalResourceVersion;

View File

@ -9,9 +9,9 @@ namespace AlicizaX.Scene.Runtime
{ {
private void Awake() private void Awake()
{ {
if (!AppServices.App.TryGet<ISceneService>(out _)) if (!AppServices.TryGetApp<ISceneService>(out _))
{ {
AppServices.App.Register(new SceneService()); AppServices.RegisterApp(new SceneService());
} }
AppServices.EnsureScene(); AppServices.EnsureScene();

View File

@ -3,7 +3,7 @@ using System;
namespace AlicizaX namespace AlicizaX
{ {
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
public interface ITimerService : IService, IServiceTickable public interface ITimerService : IService
{ {
int AddTimer(TimerHandler callback, float time, bool isLoop = false, bool isUnscaled = false, params object[] args); int AddTimer(TimerHandler callback, float time, bool isLoop = false, bool isUnscaled = false, params object[] args);
int AddTimer(TimerHandlerNoArgs callback, float time, bool isLoop = false, bool isUnscaled = false); int AddTimer(TimerHandlerNoArgs callback, float time, bool isLoop = false, bool isUnscaled = false);

View File

@ -10,7 +10,7 @@ namespace AlicizaX.Timer.Runtime
{ {
private void Awake() private void Awake()
{ {
AppServices.App.Register(new TimerService()); AppServices.RegisterApp(new TimerService());
} }
} }
} }

View File

@ -77,7 +77,7 @@ namespace AlicizaX
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
[Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)] [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
internal sealed class TimerService : ServiceBase, ITimerService internal sealed class TimerService : ServiceBase, ITimerService, IServiceTickable
{ {
private const float TimeWheelSlotInterval = 0.001f; private const float TimeWheelSlotInterval = 0.001f;

View File

@ -87,6 +87,7 @@ namespace AlicizaX.UI.Runtime
try try
{ {
Type baseType = uiType; Type baseType = uiType;
#pragma warning disable CS8632
Type? holderType = null; Type? holderType = null;
var genericArgs = baseType.GetGenericArguments(); var genericArgs = baseType.GetGenericArguments();

View File

@ -9,7 +9,7 @@ namespace AlicizaX.UI.Runtime
/// UI 模块接口:负责 UI 的创建、显示、关闭与查询。 /// UI 模块接口:负责 UI 的创建、显示、关闭与查询。
/// 支持异步与同步(预加载)两种打开方式。 /// 支持异步与同步(预加载)两种打开方式。
/// </summary> /// </summary>
public interface IUIService : IService, IServiceTickable public interface IUIService : IService
{ {
/// <summary> /// <summary>
/// 初始化 UI 模块。 /// 初始化 UI 模块。

View File

@ -7,10 +7,8 @@ using UnityEngine;
namespace AlicizaX.UI.Runtime namespace AlicizaX.UI.Runtime
{ {
internal sealed partial class UIService : ServiceBase, IUIService internal sealed partial class UIService : ServiceBase, IUIService, IServiceTickable
{ {
public int Priority { get; }
private ITimerService _timerService; private ITimerService _timerService;
protected override void OnInitialize() protected override void OnInitialize()

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -29,7 +29,7 @@ namespace AlicizaX.UI.Runtime
private void Awake() private void Awake()
{ {
_uiService = AppServices.App.Register(new UIService()); _uiService = AppServices.RegisterApp(new UIService());
if (uiRoot == null) if (uiRoot == null)
{ {
throw new GameFrameworkException("UIRoot Prefab is invalid."); throw new GameFrameworkException("UIRoot Prefab is invalid.");