/**************************************************************************** * Copyright (c) 2017 snowcold * Copyright (c) 2021.1 liangxie * * https://qframework.cn * https://github.com/liangxiegame/QFramework * https://gitee.com/liangxiegame/QFramework * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. ****************************************************************************/ using UnityEngine; namespace QFramework { using System; using System.Collections.Generic; #region 事件接口 public delegate void OnEvent(int key, params object[] param); #endregion public class QEventSystem : IPoolable,ISingleton { public static QEventSystem Instance => SingletonProperty.Instance; //private bool mIsRecycled = false; private readonly Dictionary mAllListenerMap = new Dictionary(50); public bool IsRecycled { get; set; } private QEventSystem() {} #region 内部结构 private class ListenerWrap { private LinkedList mEventList; public bool Fire(int key, params object[] param) { if (mEventList == null) { return false; } var next = mEventList.First; OnEvent call = null; LinkedListNode nextCache = null; while (next != null) { call = next.Value; nextCache = next.Next; call(key, param); next = next.Next ?? nextCache; } return true; } public bool Add(OnEvent listener) { if (mEventList == null) { mEventList = new LinkedList(); } if (mEventList.Contains(listener)) { return false; } mEventList.AddLast(listener); return true; } public void Remove(OnEvent listener) { if (mEventList == null) { return; } mEventList.Remove(listener); } public void RemoveAll() { if (mEventList == null) { return; } mEventList.Clear(); } } #endregion #region 功能函数 public bool Register(T key, OnEvent fun) where T : IConvertible { var kv = key.ToInt32(null); ListenerWrap wrap; if (!mAllListenerMap.TryGetValue(kv, out wrap)) { wrap = new ListenerWrap(); mAllListenerMap.Add(kv, wrap); } if (wrap.Add(fun)) { return true; } Debug.LogWarning("Already Register Same Event:" + key); return false; } public void UnRegister(T key, OnEvent fun) where T : IConvertible { ListenerWrap wrap; if (mAllListenerMap.TryGetValue(key.ToInt32(null), out wrap)) { wrap.Remove(fun); } } public void UnRegister(T key) where T : IConvertible { ListenerWrap wrap; if (mAllListenerMap.TryGetValue(key.ToInt32(null), out wrap)) { wrap.RemoveAll(); wrap = null; mAllListenerMap.Remove(key.ToInt32(null)); } } public bool Send(T key, params object[] param) where T : IConvertible { int kv = key.ToInt32(null); ListenerWrap wrap; if (mAllListenerMap.TryGetValue(kv, out wrap)) { return wrap.Fire(kv, param); } return false; } public void OnRecycled() { mAllListenerMap.Clear(); } #endregion #region 高频率使用的API public static bool SendEvent(T key,params object[] param) where T : IConvertible { return Instance.Send(key, param); } public static bool RegisterEvent(T key, OnEvent fun) where T : IConvertible { return Instance.Register(key, fun); } public static void UnRegisterEvent(T key, OnEvent fun) where T : IConvertible { Instance.UnRegister(key, fun); } #endregion public void OnSingletonInit() { } } }