/// 方案对比:
/// 表现层监听消息--->数据层改变发消息---->表现层收到消息,表现层改变
/// 表现层监听消息--->数据层改变会自动发消息(少写了发消息的代码),表现层改变
/// 优点:少写了发消息的代码
可以说是另外一种思路,但是也可以其他办法解决,自动发消息这个过程,这里我实现了个
核心代码
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using UnityEngine; /// <summary> /// 属性绑定 /// </summary> /// <typeparam name="T"></typeparam> public class BindableProperty<T> { private List<Action> changeList = new List<Action>(); private T _data; public BindableProperty(T data) { _data = data; } public T data { get { return _data; } set { _data = value; DispatchAll(); } } public void AddListener(Action ac) { if (!changeList.Contains(ac)) { changeList.Add(ac); } else { Debug.LogWarning("重复监听"); } } public void RemoveListener(Action ac) { if (changeList.Contains(ac)) { changeList.Remove(ac); } else { Debug.LogWarning("移除的消息不存在"); } } public void ClearListener() { changeList.Clear(); Debug.Log("清理成功"); } private void DispatchAll() { foreach (var item in changeList) { item(); } } } /// <summary> /// List /// 使用了ReadOnlyCollection作为保护,使用IReadOnlyList也是可以 /// 通过Add Remove Update Clear 对数据进行操作 /// </summary> /// <typeparam name="T"></typeparam> public class BindableList<T> { private List<Action> changeList = new List<Action>(); private List<T> _data; public BindableList() { _data = new List<T>(); } public ReadOnlyCollection<T> data { get { return _data.AsReadOnly(); } private set { } } public void Add(T t) { _data.Add(t); DispatchAll(); } public void Remove(T t) { if (_data.Contains(t)) { _data.Remove(t); DispatchAll(); } } public void Clear() { _data.Clear(); DispatchAll(); } public void Update(List<T> _list) { _data = _list; DispatchAll(); } public void AddListener(Action ac) { if (!changeList.Contains(ac)) { changeList.Add(ac); } else { Debug.LogWarning("重复监听"); } } public void RemoveListener(Action ac) { if (changeList.Contains(ac)) { changeList.Remove(ac); } else { Debug.LogWarning("移除的消息不存在"); } } public void ClearListener() { changeList.Clear(); Debug.Log("清理成功"); } private void DispatchAll() { foreach (var item in changeList) { item(); } } } /// <summary> /// Dic /// 使用IReadOnlyDictionary作为保护 /// 通过Add RemoveByKey Update Clear 对数据进行操作 /// </summary> /// <typeparam name="T"></typeparam> public class BindableDic<T,V> { private List<Action> changeList = new List<Action>(); private Dictionary<T, V> _data; public IReadOnlyDictionary<T, V> data { get { return _data; } } public BindableDic() { _data = new Dictionary<T, V>(); } public void Add(T t, V v) { _data.Add(t,v); DispatchAll(); } public void RemoveByKey(T _key) { if (_data.ContainsKey(_key)) { _data.Remove(_key); DispatchAll(); } } public void Clear() { _data.Clear(); DispatchAll(); } public void Update(Dictionary<T,V> _dic) { _data = _dic; DispatchAll(); } public void AddListener(Action ac) { if (!changeList.Contains(ac)) { changeList.Add(ac); } else { Debug.LogWarning("重复监听"); } } public void RemoveListener(Action ac) { if (changeList.Contains(ac)) { changeList.Remove(ac); } else { Debug.LogWarning("移除的消息不存在"); } } public void ClearListener() { changeList.Clear(); Debug.Log("清理成功"); } private void DispatchAll() { foreach (var item in changeList) { item(); } } }
调用,在unity实现
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 数据自动变化 /// /// 方案对比: /// 表现层监听消息--->数据层改变发消息---->表现层收到消息,表现层改变 /// 表现层监听消息--->数据层改变会自动发消息(少写了发消息的代码),表现层改变 /// 优点:少写了发消息的代码 /// </summary> public class TestBind : MonoBehaviour { BindableProperty<int> hpData = new BindableProperty<int>(100); BindableList<int> friendList = new BindableList<int>(); BindableDic<int, string> myDic = new BindableDic<int, string>(); // Start is called before the first frame update void Start() { hpData.AddListener(delegate() { print("hh" + hpData.data); }); friendList.AddListener(delegate () { print("ff" + friendList.data.Count); }); myDic.AddListener(delegate () { print("dd" + myDic.data.Count); }); } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Q)) { hpData.data = 99; } if (Input.GetKeyDown(KeyCode.W)) { friendList.Add(658); friendList.Add(638); } if (Input.GetKeyDown(KeyCode.E)) { print(friendList.data.Count); } if (Input.GetKeyDown(KeyCode.R)) { myDic.Add(1,"sas"); myDic.Add(2, "sas2212"); print(myDic.data.Count); } } }