This commit is contained in:
陈思海 2025-08-06 13:28:31 +08:00
parent ccafdeca03
commit 468a6ec694
22 changed files with 11 additions and 571 deletions

View File

@ -2,8 +2,7 @@
"name": "AlicizaX.Editor",
"rootNamespace": "",
"references": [
"GUID:75b6f2078d190f14dbda4a5b747d709c",
"GUID:2373f786d14518f44b0f475db77ba4de"
"GUID:75b6f2078d190f14dbda4a5b747d709c"
],
"includePlatforms": [
"Editor"

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 596231b03a2cf834d8b2833300d9f524
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,20 +0,0 @@
using System.IO;
using AlicizaX;
using UnityEditor;
namespace AlicizaX.Editor
{
public static class BuilderGenerate
{
public static void GeneratAppBuilderSetting(Language language, bool debugMode, int resMode)
{
const string AppBuilderSettingPath = "Assets/Resources/AppBuilderSetting.bytes";
AppBuilderSetting appBuilderSetting = new AppBuilderSetting();
appBuilderSetting.Language = language;
appBuilderSetting.DebugMode = debugMode;
appBuilderSetting.ResMode = resMode;
File.WriteAllText(AppBuilderSettingPath, Utility.Json.ToJson(appBuilderSetting));
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: c08b751d385441058a634280266803eb
timeCreated: 1737524480

View File

@ -12,6 +12,12 @@
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"versionDefines": [
{
"name": "com.alicizax.unity.cysharp.zstring",
"expression": "2.3.0",
"define": "ZSTRING_SUPPORT"
}
],
"noEngineReferences": false
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 71df78781abe4068a2c8a8fbedca8acf
timeCreated: 1736415662

View File

@ -1,8 +0,0 @@
using System;
namespace AlicizaX
{
public interface IEvent
{
}
}

View File

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

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 48751c35576345908f4dda6ef1133f4a
timeCreated: 1737376697

View File

@ -1,16 +0,0 @@
namespace AlicizaX
{
/// <summary>
/// 事件基类。
/// </summary>
public abstract class BaseEventArgs : GameFrameworkEventArgs
{
/// <summary>
/// 获取事件ID。
/// </summary>
public abstract string Id
{
get;
}
}
}

View File

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

View File

@ -1,50 +0,0 @@
namespace AlicizaX
{
public sealed partial class EventPool<T> where T : BaseEventArgs
{
/// <summary>
/// 事件结点。
/// </summary>
private sealed class EventNode : IMemory
{
private object _sender = null;
private T _eventArgs = null;
/// <summary>
/// 发送者
/// </summary>
public object Sender
{
get { return _sender; }
}
/// <summary>
/// 事件参数
/// </summary>
public T EventArgs
{
get { return _eventArgs; }
}
/// <summary>
/// 创建事件节点
/// </summary>
/// <param name="sender"></param>
/// <param name="eventArgs"></param>
/// <returns></returns>
public static EventNode Create(object sender, T eventArgs)
{
EventNode eventNodeNode = MemoryPool.Acquire<EventNode>();
eventNodeNode._sender = sender;
eventNodeNode._eventArgs = eventArgs;
return eventNodeNode;
}
public void Clear()
{
_sender = null;
_eventArgs = null;
}
}
}
}

View File

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

View File

@ -1,319 +0,0 @@
using System;
using System.Collections.Generic;
namespace AlicizaX
{
/// <summary>
/// 事件池。
/// </summary>
/// <typeparam name="T">事件类型。</typeparam>
public sealed partial class EventPool<T> where T : BaseEventArgs
{
private readonly object _lock = new object();
private readonly GameFrameworkMultiDictionary<string, EventHandler<T>> _eventHandlers;
private readonly Queue<EventNode> _events;
private readonly Dictionary<object, LinkedListNode<EventHandler<T>>> _cachedNodes;
private readonly Dictionary<object, LinkedListNode<EventHandler<T>>> _tempNodes;
private readonly EventPoolMode _eventPoolMode;
private EventHandler<T> _defaultHandler;
/// <summary>
/// 初始化事件池的新实例。
/// </summary>
/// <param name="mode">事件池模式。</param>
public EventPool(EventPoolMode mode)
{
_eventHandlers = new GameFrameworkMultiDictionary<string, EventHandler<T>>();
_events = new Queue<EventNode>();
_cachedNodes = new Dictionary<object, LinkedListNode<EventHandler<T>>>();
_tempNodes = new Dictionary<object, LinkedListNode<EventHandler<T>>>();
_eventPoolMode = mode;
_defaultHandler = null;
}
/// <summary>
/// 获取事件处理函数的数量。
/// </summary>
public int EventHandlerCount
{
get
{
lock (_lock)
{
return _eventHandlers.Count;
}
}
}
/// <summary>
/// 获取事件数量。
/// </summary>
public int EventCount
{
get
{
lock (_lock)
{
return _events.Count;
}
}
}
/// <summary>
/// 事件池轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
public void Update(float elapseSeconds, float realElapseSeconds)
{
lock (_lock)
{
while (_events.Count > 0)
{
EventNode eventNodeNode = _events.Dequeue();
HandleEvent(eventNodeNode.Sender, eventNodeNode.EventArgs);
MemoryPool.Release(eventNodeNode);
}
}
}
/// <summary>
/// 关闭并清理事件池。
/// </summary>
public void Shutdown()
{
Clear();
_eventHandlers.Clear();
_cachedNodes.Clear();
_tempNodes.Clear();
_defaultHandler = null;
}
/// <summary>
/// 清理事件。
/// </summary>
public void Clear()
{
lock (_lock)
{
_events.Clear();
}
}
/// <summary>
/// 获取事件处理函数的数量。
/// </summary>
/// <param name="id">事件类型编号。</param>
/// <returns>事件处理函数的数量。</returns>
public int Count(string id)
{
lock (_lock)
{
if (_eventHandlers.TryGetValue(id, out var listRange))
{
return listRange.Count;
}
return 0;
}
}
/// <summary>
/// 检查是否存在事件处理函数。
/// </summary>
/// <param name="id">事件类型编号。</param>
/// <param name="handler">要检查的事件处理函数。</param>
/// <returns>是否存在事件处理函数。</returns>
public bool Check(string id, EventHandler<T> handler)
{
lock (_lock)
{
if (handler == null)
{
throw new GameFrameworkException("Event handler is invalid.");
}
return _eventHandlers.Contains(id, handler);
}
}
/// <summary>
/// 订阅事件处理函数。
/// </summary>
/// <param name="id">事件类型编号。</param>
/// <param name="handler">要订阅的事件处理函数。</param>
public void Subscribe(string id, EventHandler<T> handler)
{
lock (_lock)
{
if (handler == null)
{
throw new GameFrameworkException("Event handler is invalid.");
}
if (!_eventHandlers.Contains(id))
{
_eventHandlers.Add(id, handler);
}
else if ((_eventPoolMode & EventPoolMode.AllowMultiHandler) != EventPoolMode.AllowMultiHandler)
{
throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not allow multi handler.", id));
}
else if ((_eventPoolMode & EventPoolMode.AllowDuplicateHandler) != EventPoolMode.AllowDuplicateHandler && Check(id, handler))
{
throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not allow duplicate handler.", id));
}
else
{
_eventHandlers.Add(id, handler);
}
}
}
/// <summary>
/// 取消订阅事件处理函数。
/// </summary>
/// <param name="id">事件类型编号。</param>
/// <param name="handler">要取消订阅的事件处理函数。</param>
public void Unsubscribe(string id, EventHandler<T> handler)
{
lock (_lock)
{
if (handler == null)
{
throw new GameFrameworkException("Event handler is invalid.");
}
if (_cachedNodes.Count > 0)
{
foreach (KeyValuePair<object, LinkedListNode<EventHandler<T>>> cachedNode in _cachedNodes)
{
if (cachedNode.Value != null && cachedNode.Value.Value == handler)
{
_tempNodes.Add(cachedNode.Key, cachedNode.Value.Next);
}
}
if (_tempNodes.Count > 0)
{
foreach (KeyValuePair<object, LinkedListNode<EventHandler<T>>> cachedNode in _tempNodes)
{
_cachedNodes[cachedNode.Key] = cachedNode.Value;
}
_tempNodes.Clear();
}
}
if (!_eventHandlers.Remove(id, handler))
{
throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not exists specified handler.", id));
}
}
}
/// <summary>
/// 设置默认事件处理函数。
/// </summary>
/// <param name="handler">要设置的默认事件处理函数。</param>
public void SetDefaultHandler(EventHandler<T> handler)
{
_defaultHandler = handler;
}
/// <summary>
/// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。
/// </summary>
/// <param name="sender">事件源。</param>
/// <param name="e">事件参数。</param>
public void Fire(object sender, T e)
{
lock (_lock)
{
if (e == null)
{
throw new GameFrameworkException("Event is invalid.");
}
var eventNodeNode = EventNode.Create(sender, e);
lock (_events)
{
_events.Enqueue(eventNodeNode);
}
}
}
/// <summary>
/// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。
/// </summary>
/// <param name="sender">事件源。</param>
/// <param name="e">事件参数。</param>
public void FireNow(object sender, T e)
{
lock (_lock)
{
if (e == null)
{
throw new GameFrameworkException("Event is invalid.");
}
HandleEvent(sender, e);
}
}
/// <summary>
/// 处理事件结点。
/// </summary>
/// <param name="sender">事件源。</param>
/// <param name="e">事件参数。</param>
private void HandleEvent(object sender, T e)
{
lock (_lock)
{
bool noHandlerException = false;
if (_eventHandlers.TryGetValue(e.Id, out var range))
{
LinkedListNode<EventHandler<T>> current = range.First;
while (current != null && current != range.Terminal)
{
_cachedNodes[e] = current.Next != range.Terminal ? current.Next : null;
try
{
current.Value?.Invoke(sender, e);
}
catch (Exception exception)
{
Log.Exception(exception);
}
current = _cachedNodes[e];
}
_cachedNodes.Remove(e);
}
else if (_defaultHandler != null)
{
try
{
_defaultHandler(sender, e);
}
catch (Exception exception)
{
Log.Exception(exception);
}
}
else if ((_eventPoolMode & EventPoolMode.AllowNoHandler) == 0)
{
noHandlerException = true;
}
MemoryPool.Release(e);
if (noHandlerException)
{
throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not allow no handler.", e.Id));
}
}
}
}
}

View File

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

View File

@ -1,31 +0,0 @@
using System;
namespace AlicizaX
{
/// <summary>
/// 事件池模式。
/// </summary>
[Flags]
public enum EventPoolMode : byte
{
/// <summary>
/// 默认事件池模式,即必须存在有且只有一个事件处理函数。
/// </summary>
Default = 0,
/// <summary>
/// 允许不存在事件处理函数。
/// </summary>
AllowNoHandler = 1,
/// <summary>
/// 允许存在多个事件处理函数。
/// </summary>
AllowMultiHandler = 2,
/// <summary>
/// 允许存在重复的事件处理函数。
/// </summary>
AllowDuplicateHandler = 4
}
}

View File

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

View File

@ -1,22 +0,0 @@
using System;
namespace AlicizaX
{
/// <summary>
/// 游戏框架中包含事件数据的类的基类。
/// </summary>
public abstract class GameFrameworkEventArgs : EventArgs, IMemory
{
/// <summary>
/// 初始化游戏框架中包含事件数据的类的新实例。
/// </summary>
protected GameFrameworkEventArgs()
{
}
/// <summary>
/// 清理引用。
/// </summary>
public abstract void Clear();
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: e79b33a9fb1f45dc8a82b3e4c0a73560
timeCreated: 1737376755

View File

@ -1,22 +0,0 @@
namespace AlicizaX
{
/// <summary>
/// 常用设置相关常量。
/// </summary>
public static partial class PrefsKey
{
public static class Setting
{
public const string WirtedSetting = "WirtedSetting";
public const string Language = "Setting.Language";
public const string SoundGroupMuted = "Setting.{0}Muted";
public const string SoundGroupVolume = "Setting.{0}Volume";
public const string MusicMuted = "Setting.MusicMuted";
public const string MusicVolume = "Setting.MusicVolume";
public const string SoundMuted = "Setting.SoundMuted";
public const string SoundVolume = "Setting.SoundVolume";
public const string UISoundMuted = "Setting.UISoundMuted";
public const string UISoundVolume = "Setting.UISoundVolume";
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 91862a61e413450eacc144e834e5a35b
timeCreated: 1737623610

View File

@ -1,6 +1,6 @@
using System;
#if ZSTRING_SUPPORT
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
@ -104,3 +104,4 @@ namespace AlicizaX
}
}
}
#endif