# MeowFramework **Repository Path**: Tiled-industry/MeowFramework ## Basic Information - **Project Name**: MeowFramework - **Description**: No description available - **Primary Language**: C# - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-05-13 - **Last Updated**: 2024-09-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MeowFramework<精简版QF> 文档 ## 项目概述 **项目名称:** 喵喵框架 **作者:** [PantyNeko](https://gitee.com/PantyNeko) **创建日期:** 2024-05-09 **友情链接:** 感谢 vonweller 提供的附属工具集 https://gitee.com/vw112266/meow-framework-tool-kit **描述:** 这是一个基于高性能QF架构的抠门级框架,提供了高度开放的扩展权限,适合喜欢自定义、追求极限轻量的开发者。架构旨在支持高度模块化和灵活的系统设计,实现了单例模式、命令/查询处理模式和事件处理等功能。框架的设计理念是简化开发流程,提供高效、可扩展的解决方案,适用于各种规模的项目。 ![](https://gitee.com/PantyNeko/MeowFramework/raw/main/Assets/Doc/Logo.png) ## 底层接口 ### 接口 IReceiver **用途:** 用于分离命令中的具体执行逻辑。 **示例:** ```csharp public class MyReceiver : IReceiver { // 实现细节 } ``` ### 接口 ICmd **用途:** 无参数的命令接口,用于执行不需要额外信息的操作。 **方法:** - `void Do(IModuleHub hub);` **示例:** ```csharp public class SimpleCommand : ICmd { public void Do(IModuleHub hub) { // 命令逻辑 } } ``` ### 接口 ICmd

**用途:** 带参数的命令接口,用于执行需要额外信息的操作。 **方法:** - `void Do(IModuleHub hub, P info);` **示例:** ```csharp public class ParameterizedCommand : ICmd { public void Do(IModuleHub hub, string info) { // 命令逻辑 } } ``` ### 接口 IQuery **用途:** 仅返回结果的无参数查询接口。 **方法:** - `R Do(IModuleHub hub);` **示例:** ```csharp public class SimpleQuery : IQuery { public int Do(IModuleHub hub) { // 查询逻辑 return 42; } } ``` ### 接口 IQuery **用途:** 带参数且返回结果的查询接口。 **方法:** - `R Do(IModuleHub hub, P info);` **示例:** ```csharp public class ParameterizedQuery : IQuery { public int Do(IModuleHub hub, string info) { // 查询逻辑 return info.Length; } } ``` ### 接口 IPermissionProvider **用途:** 权限提供者接口,为对象赋予访问架构的能力。 **属性:** - `IModuleHub Hub { get; }` **示例:** ```csharp public class MyPermissionProvider : IPermissionProvider { public IModuleHub Hub { get; private set; } public MyPermissionProvider(IModuleHub hub) { Hub = hub; } } ``` ### 接口 IModule **用途:** 模块接口,标识该对象为带状态模块。 **方法:** - `void TryInit();` **示例:** ```csharp public class MyModule : IModule { public void TryInit() { // 初始化逻辑 } } ``` ### 接口 IUtility **用途:** 工具接口,标识对象为无状态工具。 **示例:** ```csharp public class MyUtility : IUtility { // 工具逻辑 } ``` ### 接口 ICanInit **用途:** 可初始化接口,用于对外隐藏模块的初始化方法。 **继承:** 继承自 IModule **属性和方法:** - `bool Preload { get; }` - `void PreInit(IModuleHub hub);` - `void Deinit();` **示例:** ```csharp public class MyInitModule : ICanInit { public bool Preload => true; public void PreInit(IModuleHub hub) { // 预初始化逻辑 } public void Deinit() { // 逆初始化逻辑 } public void TryInit() { // 尝试初始化逻辑 } } ``` ### 抽象类 AbsModule **用途:** 抽象模块基类,实现基本生命周期和权限提供。 **实现的接口:** ICanInit, IPermissionProvider **属性和方法:** - `bool Inited`: 模块是否已初始化。 - `IModuleHub mHub`: 模块中心实例。 - `void ICanInit.PreInit(IModuleHub hub)`: 预初始化方法。 - `void IModule.TryInit()`: 尝试初始化方法。 - `void ICanInit.Deinit()`: 逆初始化方法。 - `protected abstract void OnInit()`: 抽象的初始化方法,由具体模块实现其初始化逻辑。 - `protected virtual void OnDeInit()`: 可重写的逆初始化方法,供具体模块实现其资源释放逻辑。 - `public virtual bool Preload => false`: 可重写的预初始化属性,用来指示是否提前初始化。 - `IModuleHub IPermissionProvider.Hub => mHub`: 实现IPermissionProvider接口,提供模块的访问能力。 **示例:** ```csharp public class MyModule : AbsModule { protected override void OnInit() { // 初始化逻辑 } protected override void OnDeInit() { // 逆初始化逻辑 } } ``` --- ## 架构工具 ### 静态类 HubTool **用途:** 提供扩展方法和工具函数。 **版本:** "1.1.1"(调试模式下) **方法和示例:** - `public static T Log(this T o)`: 在调试模式下将对象信息输出到控制台。 ```csharp "调试信息".Log(); ``` - `public static void DicLog(this Dictionary dic, string dicName, string prefix)`: 输出字典信息到控制台。 ```csharp var myDic = new Dictionary(); myDic.DicLog("myDic", "前缀信息"); ``` - `public static void Combine(this Dictionary events, Type type, Delegate evt)`: 将委托添加到字典中。 ```csharp var events = new Dictionary(); events.Combine(typeof(MyEvent), new Action(e => { /* 事件逻辑 */ })); ``` - `public static void Separate(this Dictionary events, Type type, Delegate evt)`: 将委托从字典中移除。 ```csharp var events = new Dictionary(); events.Separate(typeof(MyEvent), new Action(e => { /* 事件逻辑 */ })); ``` - `public static T GetOrAdd(this Component o) where T : Component`: 从组件获取脚本,如果获取不到就添加一个。 ```csharp var component = this.GetOrAdd(); ``` - `public static void FindComponents(this Component mono)`: 查找所有带标记的组件。 ```csharp this.FindComponents(); ``` - `public static void FindChildrenControl(this Component mono, Action callback) where T : Component`: 找到面板父节点下所有对应控件。 ```csharp this.FindChildrenControl((name, component) => { // 控件逻辑 }); ``` ### 静态类 HubEx **用途:** 提供对模块、工具、事件和命令的扩展方法。 **方法和示例:** - `public static M Module(this IPermissionProvider self) where M : class, IModule` ```csharp var myModule = this.Module(); ``` - `public static U Utility(this IPermissionProvider self) where U : class, IUtility` ```csharp var myUtility = this.Utility(); ``` - `public static IRmv AddEvent(this IPermissionProvider self, Action evt) where E : struct` ```csharp IRmv removal = this.AddEvent(e => { /* 事件处理逻辑 */ }); ``` - `public static void RmvEvent(this IPermissionProvider self, Action evt) where E : struct` ```csharp this.RmvEvent(myEventHandler); ``` - `public static void SendEvent(this IPermissionProvider self, E e) where E : struct` ```csharp this.SendEvent(new MyEvent()); ``` - `public static void SendEvent(this IPermissionProvider self) where E : struct` ```csharp this.SendEvent(); ``` - `public static IRmv AddNotify(this IPermissionProvider self, Action evt) where N : struct` ```csharp IRmv notifyRemoval = this.AddNotify(() => { /* 通知处理逻辑 */ }); ``` - `public static void RmvNotify(this IPermissionProvider self, Action evt) where N : struct` ```csharp this.RmvNotify(myNotifyHandler); ``` - `public static void SendNotify(this IPermissionProvider self) where N : struct` ```csharp this.SendNotify(); ``` - `public static void SendCmd(this IPermissionProvider self, C cmd) where C : ICmd` ```csharp this.SendCmd(new MyCommand()); ``` - `public static void SendCmd(this IPermissionProvider self) where C : struct, ICmd` ```csharp this.SendCmd(); ``` - `public static void SendCmd(this IPermissionProvider self, C cmd, P info) where C : ICmd

` ```csharp this.SendCmd(new MyParameterizedCommand(), "参数信息"); ``` - `public static void SendCmd(this IPermissionProvider self, P info) where C : struct, ICmd

` ```csharp this.SendCmd("参数信息"); ``` - `public static R Query(this IPermissionProvider self) where Q : struct, IQuery` ```csharp var result = this.Query(); ``` - `public static R Query(this IPermissionProvider self, P info) where Q : struct, IQuery` ```csharp var result = this.Query("参数信息"); ``` - `public static Q Query(this IPermissionProvider self) where Q : struct, IQuery` ```csharp var result = this.Query(); ``` - `public static Q Query(this IPermissionProvider self, P info) where Q : struct, IQuery` ```csharp var result = this.Query("参数信息"); ``` --- ## 架构接口 ### 接口 IModuleHub **用途:** 定义模块中心的接口,负责管理模块、工具、事件、通知、命令和查询。 **方法:** - `M Module() where M : class, IModule;` - `U Utility() where U : class, IUtility;` - `IRmv AddEvent(Action evt) where E : struct;` - `void RmvEvent(Action evt) where E : struct;` - `void SendEvent(E e) where E : struct;` - `void SendEvent() where E : struct;` - `IRmv AddNotify(Action evt) where N : struct;` - `void RmvNotify(Action evt) where N : struct;` - `void SendNotify() where N : struct;` - `void SendCmd(C cmd) where C : ICmd;` - `void SendCmd() where C : struct, ICmd;` - `void SendCmd(C cmd, P info) where C : ICmd

;` - `void SendCmd(P info) where C : struct, ICmd

;` - `R Query() where Q : struct, IQuery;` - `R Query(P info) where Q : struct, IQuery;` - `Q Query() where Q : struct, IQuery;` - `Q Query(P info) where Q : struct, IQuery;` --- ## 架构基类 ### 类 CustomRmv **用途:** 实现自身移除委托。 **方法:** - `void Do()` **示例:** ```csharp public class CustomRmv : IRmv { private Action call; public CustomRmv(Action call) => this.call = call; void IRmv.Do() => call?.Invoke(); } // 使用示例 IRmv rmv = new CustomRmv(() => { /* 移除逻辑 */ }); rmv.Do(); ``` ### 类 DelegateDicRmv **用途:** 实现字典中移除委托。 **方法:** - `void Do()` **示例:** ```csharp public class DelegateDicRmv : IRmv where T : struct { private Dictionary mEvents; private Delegate call; void IRmv.Do() => mEvents.Separate(typeof(T), call); public DelegateDicRmv(Dictionary events, Delegate e) { mEvents = events; call = e; } } // 使用示例 var events = new Dictionary(); var handler = new Action(e => { /* 事件逻辑 */ }); events.Combine(typeof(MyEvent), handler); IRmv rmv = new DelegateDicRmv(events, handler); rmv.Do(); ``` ### 抽象类 ModuleHub **用途:** 模块中心抽象类,负责模块和工具的管理。 **方法和属性:** - `public static IModuleHub GetIns()`: 获取单例实例。 - `protected abstract void BuildModule()`: 构建模块和工具。 - `protected void AddModule(M module) where M : IModule`: 添加模块并尝试预初始化。 - `protected void AddUtility(U utility) where U : IUtility`: 添加工具。 - `protected void Dispose()`: 释放所有已初始化模块的状态信息。 **示例:** ```csharp public abstract class MyModuleHub : ModuleHub { protected override void BuildModule() { // 构建模块和工具 AddModule(new MyModule()); AddUtility(new MyUtility()); } } // 使用示例 var hub = MyModuleHub.GetIns(); var module = hub.Module(); var utility = hub.Utility(); hub.SendCmd(new MyCommand()); var result = hub.Query(); ``` --- ## 单例模式 ### 接口 ISingleton **用途:** 单例接口。 **方法:** - `void Init();` **示例:** ```csharp public class MySingleton : ISingleton { public void Init() { // 初始化逻辑 } } ``` ### 抽象类 Singleton **用途:** 单例基类。 **属性和方法:** - `public static S GetIns()`: 获取单例实例。 **示例:** ```csharp public class MySingleton : Singleton, ISingleton { private MySingleton() { } public void Init() { // 初始化逻辑 } } // 使用示例 var instance = MySingleton.GetIns(); instance.Init(); ``` ### 抽象类 MonoSingle **用途:** Unity的Mono单例基类。 **属性和方法:** - `public static T GetIns()`: 获取单例实例。 - `protected virtual void InitSingle()`: 初始化单例。 **示例:** ```csharp public class MyMonoSingle : MonoSingle { protected override void InitSingle() { // 初始化逻辑 } } // 使用示例 var instance = MyMonoSingle.GetIns(); ``` ### 属性 FindComponentAttribute **用途:** 查找游戏物体组件的特性。 **构造函数参数:** - `string GoName`: 游戏物体名字。 - `bool GetChild`: 是否查找对应名字对象的下一级子物体。 **示例:** ```csharp public class MyComponent : MonoBehaviour { [FindComponent("ChildObject", true)] public ChildComponent childComponent; } ``` ### 抽象类 RmvTrigger **用途:** 用于在特定条件下移除事件和通知。 **方法:** - `public void Add(IRmv rmv)`: 添加需要移除的事件或通知。 - `protected void RmvAll()`: 移除所有事件和通知。 **示例:** ```csharp public class MyRmvTrigger : RmvTrigger { // 触发器逻辑 } // 使用示例 var trigger = gameObject.AddComponent(); trigger.Add(new CustomRmv(() => { /* 移除逻辑 */ })); trigger.RmvAll(); ``` ### 类 RmvOnDestroyTrigger **用途:** 在对象销毁时移除所有事件和通知。 **方法:** - `private void OnDestroy()`: 触发移除逻辑。 **示例:** ```csharp public class MyRmvOnDestroyTrigger : RmvOnDestroyTrigger { // 销毁逻辑 } // 使用示例 var trigger = gameObject.AddComponent(); trigger.Add(new CustomRmv(() => { /* 移除逻辑 */ })); // 当对象销毁时,自动调用 trigger.OnDestroy(); ``` ### 类 RmvOnDisableTrigger **用途:** 在对象失活时移除所有事件和通知。 **方法:** - `private void OnDisable()`: 触发移除逻辑。 **示例:** ```csharp public class MyRmvOnDisableTrigger : RmvOnDisableTrigger { // 失活逻辑 } // 使用示例 var trigger = gameObject.AddComponent(); trigger.Add(new CustomRmv(() => { /* 移除逻辑 */ })); // 当对象失活时,自动调用 trigger.OnDisable(); ``` ### 类 MonoKit **用途:** 提供Unity生命周期事件。 **事件:** - `public static event Action OnUpdate;` - `public static event Action OnFixedUpdate;` - `public static event Action OnLateUpdate;` - `public static event Action OnGuiUpdate;` **方法:** - `private void Awake()`: 初始化逻辑。 - `private void Update()`: 更新逻辑。 - `private void FixedUpdate()`: 固定更新逻辑。 - `private void LateUpdate()`: 延迟更新逻辑。 - `private void OnGUI()`: GUI更新逻辑。 **示例:** ```csharp public class MyMonoKit : MonoKit { // MonoKit逻辑 } // 使用示例 MonoKit.OnUpdate += () => { /* 更新逻辑 */ }; MonoKit.OnFixedUpdate += () => { /* 固定更新逻辑 */ }; MonoKit.OnLateUpdate += () => { /* 延迟更新逻辑 */ }; MonoKit.OnGuiUpdate += () => { /* GUI更新逻辑 */ }; ``` --- ## 数据绑定 ### 抽象类 PnBinder **用途:** 数据绑定基类。 **属性和方法:** - `protected Action mCallBack`: 绑定的回调函数。 - `protected V mValue`: 绑定的值。 - `public static implicit operator V(PnBinder binder)`: 隐式转换为绑定的值。 - `public IRmv RegisterWithInitValue(Action onValueChanged)`: 注册回调并立即调用。 - `public IRmv Register(Action onValueChanged)`: 注册回调。 - `public void Unregister(Action onValueChanged)`: 注销回调。 - `public void SetOnly(V value)`: 仅设置值不触发回调。 **示例:** ```csharp var binder = new PnBinder(); binder.Register(value => { /* 值变化处理逻辑 */ }); binder.SetOnly(42); int value = binder; // 隐式转换 ``` ### 类 ValueBinder **用途:** 值类型的绑定类。 **继承:** 继承自 PnBinder **方法:** - `public V Value{get;set;}`: 设置值并触发回调。 - `public static implicit operator ValueBinder(V value)`: 隐式转换为绑定类实例。 - `public static bool operator ==(ValueBinder binder, V value)`: 判断绑定的值是否相等。 - `public static bool operator !=(ValueBinder binder, V value)`: 判断绑定的值是否不等。 **示例:** ```csharp var valueBinder = 42; // 隐式转换 valueBinder.Register(value => { /* 值变化处理逻辑 */ }); valueBinder.Value = 421; int value = valueBinder; // 隐式转换 ``` ### 类 StringBinder **用途:** 字符串类型的绑定类。 **继承:** 继承自 PnBinder **方法:** - `public string Value{get;set;}`: 设置值并触发回调。 - `public static implicit operator StringBinder(string value)`: 隐式转换为绑定类实例。 - `public static bool operator ==(StringBinder binder, string value)`: 判断绑定的值是否相等。 - `public static bool operator !=(StringBinder binder, string value)`: 判断绑定的值是否不等。 **示例:** ```csharp var stringBinder = "Hello"; // 隐式转换 stringBinder.Register(value => { /* 值变化处理逻辑 */ }); stringBinder.Value = "Hello?"; string value = stringBinder; // 隐式转换 ``` ### 类 ObjectBinder **用途:** 引用类型的绑定类。 **继承:** 继承自 PnBinder **方法:** - `public void Modify(D newValue, string fieldOrPropName)`: 修改对象的字段或属性。 - `public void Modify(D newValue, Func oldValue, Action modifyAction)`: 修改对象的属性或字段。 - `public static implicit operator ObjectBinder(O value)`: 隐式转换为绑定类实例。 **示例:** ```csharp public class MyObject { public int Value; } var obj = new MyObject { Value = 10 }; var objectBinder = new ObjectBinder(obj); objectBinder.Register(value => { /* 对象变化处理逻辑 */ }); objectBinder.Modify(20, "Value"); objectBinder.Modify(30, o => o.Value, (o, newValue) => o.Value = newValue); MyObject value = objectBinder; // 隐式转换 ``` --- ## 内置模块 ### 接口 IResLoader **用途:** 定义资源加载器接口,支持同步和异步加载资源,并提供缓存机制。 **方法:** - `Task AsyncLoad(string path) where T : UnityEngine.Object;` (可重写)异步加载资源,返回 Task 在 Resources 加载中 通常Path只需要传入短链接。 - `T SyncLoad(string path) where T : UnityEngine.Object;` (可重写)同步加载资源,直接返回资源实例。 - `void AsyncLoad(string path, Action call) where T : UnityEngine.Object;` (可重写)异步加载资源,通过回调函数返回资源实例。 - `void AsyncLoadGo(string path, Action call = null);` 异步加载 GameObject,通过回调函数返回实例。 - `Task AsyncLoadGo(string path, Vector3 pos);` 异步加载 GameObject,并设置位置,返回 Task。 - `Task AsyncLoadGo(string path, Vector3 pos, Quaternion q);` 异步加载 GameObject,并设置位置和旋转,返回 Task。 - `GameObject SyncLoadGo(string path, Vector3 pos);` 同步加载 GameObject,并设置位置,返回实例。 - `GameObject SyncLoadGo(string path, Vector3 pos, Quaternion q);` 同步加载 GameObject,并设置位置和旋转,返回实例。 - `T SyncLoadFromCache(string path) where T : UnityEngine.Object;` 从缓存中同步加载资源,若缓存中不存在则加载并缓存。 - `void AsyncLoadFromCache(string path, Action call) where T : UnityEngine.Object;` 从缓存中异步加载资源,通过回调函数返回,若缓存中不存在则加载并缓存。 - `Task AsyncLoadFromCache(string path) where T : UnityEngine.Object;` 从缓存中异步加载资源,返回 Task,若缓存中不存在则加载并缓存。 ### 接口 IAudioPlayer **用途:** 定义音频播放器接口,支持播放背景音乐和音效,并提供同步和异步的播放方法。 **方法:** - `void PlayBgm(string name, float clipVolume = 1f);` 播放背景音乐 传入音频的路径和 切片音量。 ```csharp this.Module().PlayBgm("BgmName"); ``` - `void PlayBgmAsync(string name, float clipVolume = 1f);` 异步播放背景音乐 传入音频的路径和 切片音量。 ```csharp this.Module().PlayBgmAsync("BgmName"); ``` - `void PlaySound(string name, float clipVolume = 1f);` 播放音效 传入音频的路径和 切片音量。 ```csharp this.Module().PlaySound("SoundName"); ``` - `void PlaySoundAsync(string name, float clipVolume = 1f);` 异步播放音效 传入音频的路径和 切片音量。 ```csharp this.Module().PlaySoundAsync("SoundName"); ``` - `void PlaySoundCall(string name, float clipVolume = 1f);` 异步播放音效,通过回调函数返回 传入音频的路径和 切片音量。 ```csharp this.Module().PlaySoundCall("SoundName"); ``` - `void StopBgm();` 停止播放背景音乐。 ```csharp this.Module().StopBgm(); ``` - `void PauseBgm();` 暂停播放背景音乐。 ```csharp this.Module().PauseBgm(); ``` - `AudioSource GetSound(string name, float clipVolume = 1f);` 获取音效音源 传入音频的路径和 切片音量 会自主回收。 ```csharp this.Module().GetSound("SoundName").Play(); ``` - `ValueBinder BgmVolume { get; }` 获取背景音乐音量绑定器。 ```csharp this.Module().BgmVolume.Value = 0.8f; ``` - `ValueBinder SoundVolume { get; }` 获取音效音量绑定器。 ```csharp this.Module().SoundVolume.Value = 0.8f; ``` ### 接口 ITaskScheduler **用途:** 定义任务调度器接口,用于管理延迟任务、临时任务和条件任务。 **方法:** - `void AddConditionalTask(Func exitCondition, Action onFinished);` 添加一个条件任务,当指定的条件为真时执行任务。 ```csharp this.Module().AddConditionalTask(() => Time.time > 60, () => Debug.Log("Condition met after 60 seconds")); ``` - `DelayTask AddDelayTask(float duration, Action onFinished, bool isLoop = false, bool isUnScaled = false);` 添加一个延迟任务,在指定的持续时间后执行任务。 ```csharp var delayTask = this.Module().AddDelayTask(5f, () => Debug.Log("5 seconds delay task finished")); ``` - `DelayTask AddTemporaryTask(float duration, Action onUpdate, bool isUnScaled = false);` 添加一个临时任务,在指定的持续时间内每帧执行更新任务。 ```csharp var temporaryTask = this.Module().AddTemporaryTask(5f, () => Debug.Log("Temporary task updating...")); ``` ### 类 DelayTask **用途:** 定义延迟任务,支持延迟执行、循环执行和状态管理。 **方法:** - `public DelayTask Init(float delayTime, bool isLoop, Action task)` 初始化延迟任务。 ```csharp var delayTask = new DelayTask().Init(5f, false, () => Debug.Log("Task executed after 5 seconds")); ``` - `public void Start()` 开始执行任务 需先执行 Init 操作。 ```csharp delayTask.Start(); ``` ``` - `public void Pause()` 暂停任务执行。 ```csharp delayTask.Pause(); ``` - `public void Stop()` 停止任务执行。 ```csharp delayTask.Stop(); ``` ``` - `public void Complete()` 完成任务,立即执行任务。 ```csharp delayTask.Complete(); ``` - `public void Update(float delta)` 更新任务状态。 ```csharp delayTask.Update(Time.deltaTime); ``` ``` - `public void Reset()` 重置任务进度。 ```csharp delayTask.Reset(); ``` ## 容器类 ### 类 PArray **用途:** 可自动扩容的动态数组,需要手动释放未使用的结构。 **属性和方法:** - `public int Count { get; }`: 获取元素数量。 - `public int Capacity { get; }`: 获取数组容量。 - `public bool IsEmpty { get; }`: 判断数组是否为空。 - `public T First { get; }`: 获取第一个元素。 - `public T Last { get; }`: 获取最后一个元素。 - `public T this[int index] { get; set; }`: 索引器,获取或设置指定位置的元素。 - `public PArray(int capacity = 4, bool isFill = false)`: 构造函数,初始化数组容量。 - `public PArray(IEnumerable items)`: 构造函数,从集合初始化数组。 - `public PArray Clone()`: 克隆数组。 - `public void Push(T e)`: 添加元素到数组末尾。 - `public void AddLast(T e)`: 添加元素到数组末尾。 - `public void RmvLast()`: 移除最后一个元素。 - `public T Pop()`: 移除并返回最后一个元素。 - `public void RmvAt(int index)`: 交换式移除指定位置的元素。 - `public void Sort(IComparer comparer)`: 对数组进行排序。 - `public bool Find(Predicate match, out T r)`: 查找符合条件的元素。 - `public bool Contains(T e)`: 判断数组是否包含指定元素。 - `public int IndexOf(T e)`: 获取指定元素的索引。 - `public void Shrinkage()`: 缩减数组容量。 - `public void Clear()`: 清空数组元素。 - `private void Resize(int newSize)`: 调整数组大小。 - `public void ResizeToN()`: 将容量重置为当前元素数量。 - `public void ResizeToDefault()`: 将容量重置为默认值。 - `public void ResetToNoCopy(int count)`: 重置容量但不复制数据。 - `public void ToFirst()`: 重置游标。 - `public void ToLast()`: 将游标移动到数组末端。 - `public IEnumerator GetEnumerator()`: 获取迭代器。 - `IEnumerator IEnumerable.GetEnumerator()`: 获取迭代器。 **示例:** ```csharp var pArray = new PArray(10); pArray.Push(1); pArray.Push(2); pArray.Push(3); Debug.Log(pArray.First); // 输出: 1 Debug.Log(pArray.Last); // 输出: 3 pArray.Sort(Comparer.Default); foreach (var item in pArray) { Debug.Log(item); } if (pArray.Contains(2)) { Debug.Log("包含元素2"); } int index = pArray.IndexOf(3); Debug.Log($"元素3的索引: {index}"); pArray.RmvAt(1); Debug.Log(pArray.Count); // 输出: 2 pArray.Clear(); Debug.Log(pArray.IsEmpty); // 输出: true ``` --- ## UI 基类 ### 类 UIPanel **用途:** UI基类,封装找组件功能以及注册委托简化使用,提供显示或隐藏的行为。 **属性和方法:** - `public enum Layer { Top, Mid, Bot, Sys }`: UI层级枚举。 - `public virtual void OnShow()`: 显示面板时的逻辑。 - `public virtual void OnHide()`: 隐藏面板时的逻辑。 - `public virtual void Activate(bool active)`: 显示或隐藏面板。 - `protected virtual void OnClick(string btnName)`: 按钮点击时的逻辑。 - `public virtual bool IsOpen { get; }`: 判断面板是否打开。 - `protected virtual void Awake()`: 初始化逻辑,注册所有子对象的按钮。 **示例:** ```csharp public class MyUIPanel : UIPanel { protected override void OnClick(string btnName) { Debug.Log($"{btnName} clicked"); } } // 使用示例 var panel = gameObject.AddComponent(); panel.Activate(true); ``` --- ## 完整示例 ### 流程图 ![](https://gitee.com/PantyNeko/MeowFramework/raw/main/Assets/Doc/img3.png) ### 示例代码 ```csharp using UnityEngine; namespace Panty.Test { // 定义模块中心 CalcHub,负责注册模块 ICalcModel 和 IOpSystem public class CalcHub : ModuleHub { // 构建模块,在这里注册所有需要的模块 protected override void BuildModule() { // 注册计算模型模块 AddModule(new CalcModel()); // 注册操作符系统模块 AddModule(new OpSystem()); } } // 定义 CalcGame 类,作为权限提供者,允许访问 CalcHub 中的模块 public class CalcGame : MonoBehaviour, IPermissionProvider { // 实现 IPermissionProvider 接口,返回模块中心实例 IModuleHub IPermissionProvider.Hub => CalcHub.GetIns(); } // 定义 CalcUI 类,继承自 UIPanel 并实现权限提供者接口 public class CalcUI : UIPanel, IPermissionProvider { // 实现 IPermissionProvider 接口,返回模块中心实例 IModuleHub IPermissionProvider.Hub => CalcHub.GetIns(); } } namespace Panty.Test { // 定义 CalcResultQuery 结构体,实现查询接口,返回计算结果 public struct CalcResultQuery : IQuery { // 实现 Do 方法,执行查询操作,返回计算结果 public float Do(IModuleHub hub) { // 获取计算模型模块 var model = hub.Module(); // 获取当前操作符 string op = hub.Module().Op; // 获取两个操作数 int a = model.NumA; int b = model.NumB; // 根据操作符执行相应的计算 return op switch { "+" => a + b, "-" => a - b, "*" => (float)a * b, "/" => (float)a / b, _ => int.MaxValue, }; } } // 定义 NextOpIndexCmd 结构体,实现命令接口,用于切换操作符 public struct NextOpIndexCmd : ICmd { // 实现 Do 方法,执行命令操作,切换操作符索引并发送计算命令 public void Do(IModuleHub hub) { // 获取操作符系统模块 hub.Module().NextOpIndex(); // 发送计算命令 hub.SendCmd(); } } // 定义 RandomCalcCmd 结构体,实现命令接口,用于生成随机数并发送计算命令 public struct RandomCalcCmd : ICmd { // 实现 Do 方法,执行命令操作,生成随机数并发送计算命令 public void Do(IModuleHub hub) { // 获取计算模型模块 var model = hub.Module(); // 生成随机数并赋值给操作数A和B model.NumA.Value = Random.Range(1, 100); model.NumB.Value = Random.Range(1, 100); // 发送计算命令 hub.SendCmd(); } } // 定义 CalcCmd 结构体,实现命令接口,用于执行计算并发送事件 public struct CalcCmd : ICmd { // 实现 Do 方法,执行计算命令,查询计算结果并发送计算事件 public void Do(IModuleHub hub) { // 查询计算结果 var result = hub.Query(); // 发送计算结果事件 hub.SendEvent(new CalcEvent() { result = result }); } } // 定义 OpChangeEvent 结构体,用于表示操作符变化事件 public struct OpChangeEvent { // 表示当前操作符 public string op; } // 定义 CalcEvent 结构体,用于表示计算结果事件 public struct CalcEvent { // 表示计算结果 public float result; } // 定义 IOpSystem 接口,用于表示操作符系统 public interface IOpSystem : IModule { // 获取当前操作符 string Op { get; } // 切换到下一个操作符 void NextOpIndex(); } // 定义 OpSystem 类,实现操作符系统 public class OpSystem : AbsModule, IOpSystem { // 操作符索引 private int opIndex; // 操作符数组 private string[] ops; // 获取当前操作符 public string Op => ops[opIndex]; // 实现模块初始化方法,初始化操作符数组和索引 protected override void OnInit() { ops = new string[4] { "+", "-", "*", "/" }; opIndex = 0; } // 切换到下一个操作符 public void NextOpIndex() { opIndex = (opIndex + 1) % ops.Length; // 发送操作符变化事件 this.SendEvent(new OpChangeEvent() { op = ops[opIndex] }); } } // 定义 ICalcModel 接口,用于表示计算模型 public interface ICalcModel : IModule { // 操作数A ValueBinder NumA { get; } // 操作数B ValueBinder NumB { get; } } // 定义 CalcModel 类,实现计算模型 public class CalcModel : AbsModule, ICalcModel { // 初始化操作数A和B的绑定器 public ValueBinder NumA { get; } = new ValueBinder(1); public ValueBinder NumB { get; } = new ValueBinder(2); // 实现模块初始化方法 protected override void OnInit() { } } } namespace Panty.Test { // 定义 CalcPanel 类,继承自 CalcUI,负责管理 UI 逻辑 public class CalcPanel : CalcUI { // 查找并绑定 UI 组件 [FindComponent("Op")] private Text mOPText; [FindComponent("Result")] private Text mResultText; [FindComponent("InputA")] private Text mInputA; [FindComponent("InputB")] private Text mInputB; // 存储计算模型模块实例 private ICalcModel mModel; // 初始化方法,在 Start 中注册操作数和事件的回调 private void Start() { // 获取计算模型模块 mModel = this.Module(); // 注册操作数A和B的值变化回调,并在销毁时移除 mModel.NumA.RegisterWithInitValue(v => mInputA.text = v.ToString()).RmvOnDestroy(this); mModel.NumB.RegisterWithInitValue(v => mInputB.text = v.ToString()).RmvOnDestroy(this); // 注册计算结果事件的回调,并在销毁时移除 this.AddEvent(e => mResultText.text = e.result.ToString()).RmvOnDestroy(this); // 注册操作符变化事件的回调,并在销毁时移除 this.AddEvent(e => mOPText.text = e.op).RmvOnDestroy(this); } // 处理按钮点击事件 protected override void OnClick(string btnName) { // 根据按钮名称执行不同的命令 switch (btnName) { case "Op": // 切换操作符 this.SendCmd(); break; case "Eq": // 执行计算 this.SendCmd(); break; case "Add_NumA": // 增加操作数A mModel.NumA.Value++; break; case "Add_NumB": // 增加操作数B mModel.NumB.Value++; break; case "Sub_NumA": // 减少操作数A mModel.NumA.Value--; break; case "Sub_NumB": // 减少操作数B mModel.NumB.Value--; break; case "Random": // 生成随机数并执行计算 this.SendCmd(); break; } } } } ```