Compare commits

..

No commits in common. "e7a4150495c8971b197074135c5f5cd5d1be4e02" and "c4c9a22fc42bc8ef9052040cd162ce865c588464" have entirely different histories.

38 changed files with 263 additions and 242 deletions

View File

@ -7,87 +7,67 @@ namespace AlicizaX
private static ServiceWorld _world; private static ServiceWorld _world;
public static bool HasWorld => _world != null; public static bool HasWorld => _world != null;
internal static ServiceWorld EnsureWorld(int appScopeOrder = ServiceDomainOrder.App) public static bool HasScene => _world != null && _world.HasScene;
public static bool HasGameplay => _world != null && _world.HasGameplay;
public static ServiceWorld World
{
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;
} }
internal static ServiceWorld RequireWorld() public static ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene)
=> World.EnsureScene(order);
public static bool TryGetScene(out ServiceScope scope)
{ {
if (_world == null) if (_world == null) { scope = null; return false; }
throw new InvalidOperationException("ServiceWorld has not been created yet."); return _world.TryGetScene(out scope);
return _world;
} }
public static T RegisterApp<T>(T service, params Type[] extraContracts) where T : class, IService public static ServiceScope ResetScene(int order = ServiceDomainOrder.Scene)
=> RequireWorld().App.Register(service, extraContracts); => World.ResetScene(order);
public static bool TryGetApp<T>(out T service) where T : class, IService 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) if (_world == null) { scope = null; return false; }
{ return _world.TryGetGameplay(out scope);
service = null;
return false;
}
return _world.App.TryGet(out service);
} }
public static T RequireApp<T>() where T : class, IService public static bool DestroyGameplay()
=> RequireWorld().App.Require<T>(); => _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
{ {
if (_world == null) if (_world == null) { service = null; return false; }
{
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
=> RequireWorld().Require<T>(); => World.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,5 +2,7 @@ namespace AlicizaX
{ {
public interface IService public interface IService
{ {
void Initialize(ServiceContext context);
void Destroy();
} }
} }

View File

@ -1,11 +0,0 @@
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

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

View File

@ -1,18 +1,16 @@
namespace AlicizaX namespace AlicizaX
{ {
internal interface IServiceLifecycle public abstract class ServiceBase : IService
{ {
void Initialize(ServiceContext context); public ServiceContext Context { get; private set; }
void Destroy();
}
public abstract class ServiceBase : IService, IServiceLifecycle public bool IsInitialized { get; private set; }
{
protected ServiceContext Context { 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 +20,7 @@ namespace AlicizaX
OnInitialize(); OnInitialize();
} }
void IServiceLifecycle.Destroy() void IService.Destroy()
{ {
if (!IsInitialized) return; if (!IsInitialized) return;

View File

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

View File

@ -8,13 +8,11 @@ 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
{ {
internal sealed class ServiceScope : IDisposable, IServiceRegistry public sealed class ServiceScope : IDisposable
{ {
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;
} }
internal ServiceWorld World { get; } public ServiceWorld World { get; }
public string Name { get; } public string Name { get; }
internal int Order { get; } public int Order { get; }
internal bool IsDisposed { get; private set; } public 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,9 +47,6 @@ 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))
@ -73,7 +70,7 @@ namespace AlicizaX
try try
{ {
lifecycle.Initialize(new ServiceContext(World, this)); service.Initialize(new ServiceContext(World, this));
AddToLifecycleLists(service); AddToLifecycleLists(service);
} }
catch catch
@ -97,12 +94,9 @@ 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);
lifecycle.Destroy(); service.Destroy();
return true; return true;
} }
@ -161,11 +155,9 @@ 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
lifecycle.Destroy(); service.Destroy();
} }
_registrationOrder.Clear(); _registrationOrder.Clear();

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace AlicizaX namespace AlicizaX
{ {
internal sealed class ServiceWorld : IDisposable public 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,18 +13,20 @@ namespace AlicizaX
private ServiceScope _sceneScope; private ServiceScope _sceneScope;
private ServiceScope _gameplayScope; private ServiceScope _gameplayScope;
internal ServiceWorld(int appScopeOrder = ServiceDomainOrder.App) public ServiceWorld(int appScopeOrder = ServiceDomainOrder.App)
{ {
App = CreateScopeInternal(typeof(AppScope), nameof(App), appScopeOrder); App = CreateScopeInternal(typeof(AppScope), nameof(AppScope), appScopeOrder);
} }
internal ServiceScope App { get; } public ServiceScope App { get; }
internal bool HasScene => _sceneScope != null && !_sceneScope.IsDisposed; public ServiceScope AppScope => App;
internal bool HasGameplay => _gameplayScope != null && !_gameplayScope.IsDisposed; public bool HasScene => _sceneScope != null && !_sceneScope.IsDisposed;
internal ServiceScope Scene public bool HasGameplay => _gameplayScope != null && !_gameplayScope.IsDisposed;
public ServiceScope Scene
{ {
get get
{ {
@ -34,7 +36,7 @@ namespace AlicizaX
} }
} }
internal ServiceScope Gameplay public ServiceScope Gameplay
{ {
get get
{ {
@ -44,24 +46,24 @@ namespace AlicizaX
} }
} }
internal ServiceScope EnsureScene(int order = ServiceDomainOrder.Scene) public 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);
internal bool TryGetScene(out ServiceScope scope) public bool TryGetScene(out ServiceScope scope)
{ {
scope = HasScene ? _sceneScope : null; scope = HasScene ? _sceneScope : null;
return scope != null; return scope != null;
} }
internal ServiceScope ResetScene(int order = ServiceDomainOrder.Scene) public ServiceScope ResetScene(int order = ServiceDomainOrder.Scene)
{ {
DestroyScene(); DestroyScene();
return EnsureScene(order); return EnsureScene(order);
} }
internal bool DestroyScene() public bool DestroyScene()
{ {
if (!HasScene) if (!HasScene)
return false; return false;
@ -71,18 +73,18 @@ namespace AlicizaX
return DestroyScope(scope, typeof(SceneScope)); return DestroyScope(scope, typeof(SceneScope));
} }
internal ServiceScope EnsureGameplay(int order = ServiceDomainOrder.Gameplay) public 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);
internal bool TryGetGameplay(out ServiceScope scope) public bool TryGetGameplay(out ServiceScope scope)
{ {
scope = HasGameplay ? _gameplayScope : null; scope = HasGameplay ? _gameplayScope : null;
return scope != null; return scope != null;
} }
internal bool DestroyGameplay() public bool DestroyGameplay()
{ {
if (!HasGameplay) if (!HasGameplay)
return false; return false;
@ -92,10 +94,10 @@ namespace AlicizaX
return DestroyScope(scope, typeof(GameplayScope)); return DestroyScope(scope, typeof(GameplayScope));
} }
internal 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);
internal bool TryGet<T>(ServiceScope preferredScope, out T service) where T : class, IService public 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;
@ -112,33 +114,33 @@ namespace AlicizaX
return false; return false;
} }
internal T Require<T>() where T : class, IService => Require<T>(null); public T Require<T>() where T : class, IService => Require<T>(null);
internal T Require<T>(ServiceScope preferredScope) where T : class, IService public 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.");
} }
internal void Tick(float deltaTime) public 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);
} }
internal void LateTick(float deltaTime) public 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);
} }
internal void FixedTick(float fixedDeltaTime) public 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);
} }
internal void DrawGizmos() public 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.RequireWorld().Tick(Time.deltaTime); if (AppServices.HasWorld) AppServices.World.Tick(Time.deltaTime);
} }
protected virtual void LateUpdate() protected virtual void LateUpdate()
{ {
if (AppServices.HasWorld) AppServices.RequireWorld().LateTick(Time.deltaTime); if (AppServices.HasWorld) AppServices.World.LateTick(Time.deltaTime);
} }
protected virtual void FixedUpdate() protected virtual void FixedUpdate()
{ {
if (AppServices.HasWorld) AppServices.RequireWorld().FixedTick(Time.fixedDeltaTime); if (AppServices.HasWorld) AppServices.World.FixedTick(Time.fixedDeltaTime);
} }
protected virtual void OnDrawGizmos() protected virtual void OnDrawGizmos()
{ {
if (AppServices.HasWorld) AppServices.RequireWorld().DrawGizmos(); if (AppServices.HasWorld) AppServices.World.DrawGizmos();
} }
protected virtual async void OnDestroy() protected virtual async void OnDestroy()
@ -68,6 +68,6 @@ namespace AlicizaX
} }
protected virtual void RegisterAppServices(IServiceRegistry appServices) { } protected virtual void RegisterAppServices(ServiceScope appScope) { }
} }
} }

View File

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

View File

@ -42,7 +42,7 @@ namespace AlicizaX.ObjectPool
/// <summary> /// <summary>
/// 对象池管理器。 /// 对象池管理器。
/// </summary> /// </summary>
public interface IObjectPoolService : IService public interface IObjectPoolService : IService, IServiceTickable
{ {
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.RegisterApp(new ObjectPoolService()); _mObjectPoolService = AppServices.App.Register(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, IServiceTickable internal sealed partial class ObjectPoolService : ServiceBase, IObjectPoolService
{ {
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 e.Message; return string.Empty;
} }
} }

View File

@ -81,9 +81,9 @@ namespace AlicizaX
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false; UnityEditor.EditorApplication.isPlaying = false;
#else return;
Application.Quit();
#endif #endif
Application.Quit();
} }
#if UNITY_IOS #if UNITY_IOS
@ -98,7 +98,9 @@ namespace AlicizaX
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
Application.OpenURL(url); Application.OpenURL(url);
#elif UNITY_IOS return;
#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.RegisterApp(new UtilityLoopService()); _loopService = AppServices.App.Register(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.RegisterApp(new AudioService()); _audioService = AppServices.App.Register(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, IServiceTickable internal class AudioService : ServiceBase, IAudioService
{ {
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 public interface IAudioService:IService, IServiceTickable
{ {
/// <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>
/// 榛樿璋冭瘯鍣ㄧ獥鍙eぇ灏忋€? /// 暺䁅恕靚<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>
/// 榛樿璋冭瘯鍣ㄧ獥鍙g缉鏀炬瘮渚嬨€? /// 暺䁅恕靚<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.RegisterApp(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>
/// 娉ㄥ唽璋冭瘯鍣ㄧ獥鍙c€? /// 瘜典<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
/// </summary> /// </summary>
/// <param name="path">璋冭瘯鍣ㄧ獥鍙h矾寰勩€?/param> /// <param name="path"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param>
/// <param name="debuggerWindow">瑕佹敞鍐岀殑璋冭瘯鍣ㄧ獥鍙c€?/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>
/// 瑙i櫎娉ㄥ唽璋冭瘯鍣ㄧ獥鍙c€? /// <EFBFBD>膄瘜典<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
/// </summary> /// </summary>
/// <param name="path">璋冭瘯鍣ㄧ獥鍙h矾寰勩€?/param> /// <param name="path"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param>
/// <returns>鏄惁瑙i櫎娉ㄥ唽璋冭瘯鍣ㄧ獥鍙f垚鍔熴€?/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>
/// 鑾峰彇璋冭瘯鍣ㄧ獥鍙c€? /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
/// </summary> /// </summary>
/// <param name="path">璋冭瘯鍣ㄧ獥鍙h矾寰勩€?/param> /// <param name="path"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param>
/// <returns>瑕佽幏鍙栫殑璋冭瘯鍣ㄧ獥鍙c€?/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>
/// 閫変腑璋冭瘯鍣ㄧ獥鍙c€? /// <EFBFBD>劐葉靚<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
/// </summary> /// </summary>
/// <param name="path">璋冭瘯鍣ㄧ獥鍙h矾寰勩€?/param> /// <param name="path"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>楝敺<EFBFBD><EFBFBD>?/param>
/// <returns>鏄惁鎴愬姛閫変腑璋冭瘯鍣ㄧ獥鍙c€?/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>
/// 杩樺師璋冭瘯鍣ㄧ獥鍙e竷灞€銆? /// 餈睃<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);

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, IServiceTickable internal sealed partial class DebuggerService : ServiceBase, IDebuggerService
{ {
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 public interface IDebuggerService:IService, IServiceTickable
{ {
/// <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.RequireApp<IAudioService>(); _audio = AppServices.App.Require<IAudioService>();
} }
return _audio; return _audio;
@ -42,7 +42,7 @@ public static partial class GameApp
{ {
if (_localization == null) if (_localization == null)
{ {
_localization = AppServices.RequireApp<ILocalizationService>(); _localization = AppServices.App.Require<ILocalizationService>();
} }
return _localization; return _localization;
@ -60,7 +60,7 @@ public static partial class GameApp
{ {
if (_objectPool == null) if (_objectPool == null)
{ {
_objectPool = AppServices.RequireApp<IObjectPoolService>(); _objectPool = AppServices.App.Require<IObjectPoolService>();
} }
return _objectPool; return _objectPool;
@ -79,7 +79,7 @@ public static partial class GameApp
{ {
if (_procedure == null) if (_procedure == null)
{ {
_procedure = AppServices.RequireApp<IProcedureService>(); _procedure = AppServices.App.Require<IProcedureService>();
} }
return _procedure; return _procedure;
@ -98,7 +98,7 @@ public static partial class GameApp
{ {
if (_resource == null) if (_resource == null)
{ {
_resource = AppServices.RequireApp<IResourceService>(); _resource = AppServices.App.Require<IResourceService>();
} }
return _resource; return _resource;
@ -116,7 +116,7 @@ public static partial class GameApp
{ {
if (_scene == null) if (_scene == null)
{ {
_scene = AppServices.RequireApp<ISceneService>(); _scene = AppServices.App.Require<ISceneService>();
} }
return _scene; return _scene;
@ -134,7 +134,7 @@ public static partial class GameApp
{ {
if (_timer == null) if (_timer == null)
{ {
_timer = AppServices.RequireApp<ITimerService>(); _timer = AppServices.App.Require<ITimerService>();
} }
return _timer; return _timer;
@ -153,7 +153,7 @@ public static partial class GameApp
{ {
if (_ui == null) if (_ui == null)
{ {
_ui = AppServices.RequireApp<IUIService>(); _ui = AppServices.App.Require<IUIService>();
} }
return _ui; return _ui;

View File

@ -53,9 +53,9 @@ namespace AlicizaX.Localization.Runtime
private void Start() private void Start()
{ {
if (!AppServices.TryGetApp<ILocalizationService>(out _mLocalizationService)) if (!AppServices.App.TryGet<ILocalizationService>(out _mLocalizationService))
{ {
_mLocalizationService = AppServices.RegisterApp(new LocalizationService()); _mLocalizationService = AppServices.App.Register(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 public interface IProcedureService : IService, IServiceTickable
{ {
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.RegisterApp(new ProcedureService()); AppServices.App.Register(new ProcedureService());
} }
} }
} }

View File

@ -4,7 +4,7 @@ using UnityEngine;
namespace AlicizaX namespace AlicizaX
{ {
internal class ProcedureService : ServiceBase, IProcedureService, IServiceTickable internal class ProcedureService : ServiceBase, IProcedureService
{ {
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,6 +6,9 @@ using YooAsset;
namespace AlicizaX.Resource.Runtime namespace AlicizaX.Resource.Runtime
{ {
/// <summary>
/// 资源组件<E7BB84>?
/// </summary>
[DisallowMultipleComponent] [DisallowMultipleComponent]
public class ResourceComponent : MonoBehaviour public class ResourceComponent : MonoBehaviour
{ {
@ -37,14 +40,26 @@ 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;
@ -52,11 +67,16 @@ 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;
@ -71,31 +91,46 @@ 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;
@ -106,28 +141,36 @@ 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;
@ -148,7 +191,7 @@ namespace AlicizaX.Resource.Runtime
private void Awake() private void Awake()
{ {
_resourceService = AppServices.RegisterApp(new ResourceService()); _resourceService = AppServices.App.Register(new ResourceService());
Application.lowMemory += OnLowMemory; Application.lowMemory += OnLowMemory;
} }
@ -173,7 +216,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()
@ -181,8 +224,12 @@ 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,6 +37,12 @@ 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.TryGetApp<ISceneService>(out _)) if (!AppServices.App.TryGet<ISceneService>(out _))
{ {
AppServices.RegisterApp(new SceneService()); AppServices.App.Register(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 public interface ITimerService : IService, IServiceTickable
{ {
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.RegisterApp(new TimerService()); AppServices.App.Register(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, IServiceTickable internal sealed class TimerService : ServiceBase, ITimerService
{ {
private const float TimeWheelSlotInterval = 0.001f; private const float TimeWheelSlotInterval = 0.001f;

View File

@ -87,7 +87,6 @@ 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 public interface IUIService : IService, IServiceTickable
{ {
/// <summary> /// <summary>
/// 初始化 UI 模块。 /// 初始化 UI 模块。

View File

@ -7,8 +7,10 @@ using UnityEngine;
namespace AlicizaX.UI.Runtime namespace AlicizaX.UI.Runtime
{ {
internal sealed partial class UIService : ServiceBase, IUIService, IServiceTickable internal sealed partial class UIService : ServiceBase, IUIService
{ {
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.RegisterApp(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.");