-
Notifications
You must be signed in to change notification settings - Fork 790
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
v1.0.143 新增 BindableDictionary 及 Example、文档
- Loading branch information
1 parent
1486953
commit e0b0885
Showing
8 changed files
with
328 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
+1.21 KB
(130%)
QFramework.Unity2018+/Assets/QFramework/Toolkits/_CoreKit/BindableKit/Example.unitypackage
Binary file not shown.
190 changes: 190 additions & 0 deletions
190
....Unity2018+/Assets/QFramework/Toolkits/_CoreKit/BindableKit/Scripts/BindableDictionary.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
/**************************************************************************** | ||
* Copyright (c) 2016 - 2024 liangxiegame UNDER MIT License | ||
* | ||
* https://qframework.cn | ||
* https://github.com/liangxiegame/QFramework | ||
* https://gitee.com/liangxiegame/QFramework | ||
****************************************************************************/ | ||
|
||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Runtime.Serialization; | ||
|
||
namespace QFramework | ||
{ | ||
[Serializable] | ||
public class BindableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, | ||
IDictionary,ISerializable, IDeserializationCallback | ||
{ | ||
private readonly Dictionary<TKey, TValue> mInner; | ||
|
||
public BindableDictionary() => mInner = new Dictionary<TKey, TValue>(); | ||
public BindableDictionary(IEqualityComparer<TKey> comparer) => mInner = new Dictionary<TKey, TValue>(comparer); | ||
public BindableDictionary(Dictionary<TKey, TValue> innerDictionary) => mInner = innerDictionary; | ||
|
||
public TValue this[TKey key] | ||
{ | ||
get => mInner[key]; | ||
set | ||
{ | ||
TValue oldValue; | ||
if (TryGetValue(key, out oldValue)) | ||
{ | ||
mInner[key] = value; | ||
mOnReplace?.Trigger(key, oldValue, value); | ||
} | ||
else | ||
{ | ||
mInner[key] = value; | ||
mOnAdd?.Trigger(key, value); | ||
mOnCountChanged?.Trigger(Count); | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
public int Count => mInner.Count; | ||
public Dictionary<TKey, TValue>.KeyCollection Keys => mInner.Keys; | ||
public Dictionary<TKey, TValue>.ValueCollection Values => mInner.Values; | ||
|
||
public void Add(TKey key, TValue value) | ||
{ | ||
mInner.Add(key, value); | ||
|
||
mOnAdd?.Trigger(key, value); | ||
mOnCountChanged?.Trigger(Count); | ||
} | ||
|
||
public void Clear() | ||
{ | ||
var beforeCount = Count; | ||
mInner.Clear(); | ||
|
||
mOnClear?.Trigger(); | ||
if (beforeCount > 0) | ||
{ | ||
mOnCountChanged?.Trigger(Count); | ||
} | ||
} | ||
|
||
public bool Remove(TKey key) | ||
{ | ||
TValue oldValue; | ||
if (mInner.TryGetValue(key, out oldValue)) | ||
{ | ||
var isSuccessRemove = mInner.Remove(key); | ||
if (isSuccessRemove) | ||
{ | ||
mOnRemove?.Trigger(key, oldValue); | ||
mOnCountChanged?.Trigger(Count); | ||
} | ||
return isSuccessRemove; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public bool ContainsKey(TKey key) => mInner.ContainsKey(key); | ||
|
||
public bool TryGetValue(TKey key, out TValue value) => mInner.TryGetValue(key, out value); | ||
|
||
public Dictionary<TKey, TValue>.Enumerator GetEnumerator() => mInner.GetEnumerator(); | ||
|
||
|
||
[NonSerialized] | ||
private EasyEvent<int> mOnCountChanged; | ||
public EasyEvent<int> OnCountChanged => mOnCountChanged ?? (mOnCountChanged = new EasyEvent<int>()); | ||
|
||
|
||
[NonSerialized] | ||
private EasyEvent mOnClear; | ||
public EasyEvent OnClear => mOnClear ?? (mOnClear = new EasyEvent()); | ||
|
||
[NonSerialized] | ||
private EasyEvent<TKey, TValue> mOnAdd; | ||
public EasyEvent<TKey, TValue> OnAdd => mOnAdd ?? (mOnAdd = new EasyEvent<TKey, TValue>()); | ||
|
||
[NonSerialized] | ||
private EasyEvent<TKey,TValue> mOnRemove; | ||
public EasyEvent<TKey, TValue> OnRemove => mOnRemove ?? (mOnRemove = new EasyEvent<TKey, TValue>()); | ||
|
||
[NonSerialized] | ||
private EasyEvent<TKey, TValue,TValue> mOnReplace; | ||
|
||
/// <summary> | ||
/// TKey:key | ||
/// TValue:oldValue | ||
/// TValue:newValue | ||
/// </summary> | ||
public EasyEvent<TKey, TValue,TValue> OnReplace => mOnReplace ?? (mOnReplace = new EasyEvent<TKey, TValue, TValue>()); | ||
|
||
|
||
|
||
#region implement explicit | ||
object IDictionary.this[object key] | ||
{ | ||
get => this[(TKey)key]; | ||
set => this[(TKey)key] = (TValue)value; | ||
} | ||
bool IDictionary.IsFixedSize => ((IDictionary)mInner).IsFixedSize; | ||
|
||
bool IDictionary.IsReadOnly => ((IDictionary)mInner).IsReadOnly; | ||
|
||
bool ICollection.IsSynchronized => ((IDictionary)mInner).IsSynchronized; | ||
|
||
ICollection IDictionary.Keys => ((IDictionary)mInner).Keys; | ||
|
||
object ICollection.SyncRoot => ((IDictionary)mInner).SyncRoot; | ||
|
||
ICollection IDictionary.Values => ((IDictionary)mInner).Values; | ||
|
||
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => ((ICollection<KeyValuePair<TKey, TValue>>)mInner).IsReadOnly; | ||
|
||
ICollection<TKey> IDictionary<TKey, TValue>.Keys => mInner.Keys; | ||
|
||
ICollection<TValue> IDictionary<TKey, TValue>.Values => mInner.Values; | ||
|
||
void IDictionary.Add(object key, object value) => Add((TKey)key, (TValue)value); | ||
|
||
bool IDictionary.Contains(object key) => ((IDictionary)mInner).Contains(key); | ||
|
||
void ICollection.CopyTo(Array array, int index) => ((IDictionary)mInner).CopyTo(array, index); | ||
|
||
public void GetObjectData(SerializationInfo info, StreamingContext context) => ((ISerializable)mInner).GetObjectData(info, context); | ||
|
||
public void OnDeserialization(object sender) => ((IDeserializationCallback)mInner).OnDeserialization(sender); | ||
|
||
void IDictionary.Remove(object key) => Remove((TKey)key); | ||
|
||
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value); | ||
|
||
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) => ((ICollection<KeyValuePair<TKey, TValue>>)mInner).Contains(item); | ||
|
||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) => ((ICollection<KeyValuePair<TKey, TValue>>)mInner).CopyTo(array, arrayIndex); | ||
|
||
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() => ((ICollection<KeyValuePair<TKey, TValue>>)mInner).GetEnumerator(); | ||
|
||
IEnumerator IEnumerable.GetEnumerator() => mInner.GetEnumerator(); | ||
|
||
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) | ||
{ | ||
TValue v; | ||
if (TryGetValue(item.Key, out v)) | ||
{ | ||
if (EqualityComparer<TValue>.Default.Equals(v, item.Value)) | ||
{ | ||
Remove(item.Key); | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
IDictionaryEnumerator IDictionary.GetEnumerator() => ((IDictionary)mInner).GetEnumerator(); | ||
|
||
#endregion | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...y2018+/Assets/QFramework/Toolkits/_CoreKit/BindableKit/Scripts/BindableDictionary.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
2 changes: 1 addition & 1 deletion
2
....0 之后新增功能/20240918. 新增 BindableList 功能.md → ... v1.0 之后新增功能/20240918. 新增 BindableList.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# 20240918. 新增 BindableList 功能 | ||
# 20240918. 新增 BindableList | ||
|
||
BindableProperty 很好用,但是不支持 List 等集合。 | ||
|
||
|
File renamed without changes.
119 changes: 119 additions & 0 deletions
119
...tor/Resources/EditorGuideline/5. v1.0 之后新增功能/20240919. 新增 BindableDictionary.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# 20240919. 新增 BindableDictionary | ||
|
||
虽然笔者目前还不知道 BindableDictionary 能用在什么使用场景下,但是还是应童鞋的要求实现了 BindableDictionary。 | ||
|
||
基本使用如下: | ||
|
||
``` csharp | ||
using System.Linq; | ||
using UnityEngine; | ||
|
||
namespace QFramework.Example | ||
{ | ||
public class BindableDictionaryExample : MonoBehaviour | ||
{ | ||
private BindableDictionary<string, string> mDictionary = new BindableDictionary<string, string>(); | ||
|
||
private void Start() | ||
{ | ||
mDictionary.OnCountChanged.Register(count => | ||
{ | ||
print("count:" + count); | ||
}).UnRegisterWhenGameObjectDestroyed(gameObject); | ||
|
||
mDictionary.OnAdd.Register((key, value) => | ||
{ | ||
print("add:" + key + "," + value); | ||
}).UnRegisterWhenGameObjectDestroyed(gameObject); | ||
|
||
mDictionary.OnRemove.Register((key, value) => | ||
{ | ||
print("remove:" + key + "," + value); | ||
}).UnRegisterWhenGameObjectDestroyed(gameObject); | ||
|
||
mDictionary.OnReplace.Register((key, oldValue,newValue) => | ||
{ | ||
print("replace:" + key + "," + oldValue + "," + newValue); | ||
}).UnRegisterWhenGameObjectDestroyed(gameObject); | ||
|
||
mDictionary.OnClear.Register(() => | ||
{ | ||
print("clear"); | ||
}).UnRegisterWhenGameObjectDestroyed(gameObject); | ||
} | ||
|
||
private string mKeyToDelete = null; | ||
private void OnGUI() | ||
{ | ||
IMGUIHelper.SetDesignResolution(640,360); | ||
|
||
GUILayout.Label("Count:" + mDictionary.Count); | ||
GUILayout.BeginVertical("box"); | ||
|
||
foreach (var kv in mDictionary) | ||
{ | ||
GUILayout.BeginHorizontal("box"); | ||
GUILayout.Label($"{kv.Key},{kv.Value}"); | ||
if (GUILayout.Button("-")) | ||
{ | ||
mKeyToDelete = kv.Key; | ||
} | ||
|
||
GUILayout.EndHorizontal(); | ||
} | ||
|
||
if (GUILayout.Button("add")) | ||
{ | ||
var key = "key" + Random.Range(0, 100); | ||
if (!mDictionary.ContainsKey(key)) | ||
{ | ||
mDictionary.Add("key" + Random.Range(0,100),"value" + Random.Range(0,100)); | ||
} | ||
} | ||
|
||
if (mDictionary.Count > 0) | ||
{ | ||
if (GUILayout.Button("remove")) | ||
{ | ||
mDictionary.Remove(mDictionary.Keys.First()); | ||
} | ||
|
||
if (GUILayout.Button("replace")) | ||
{ | ||
mDictionary[mDictionary.Keys.First()] = "replaced value" + Random.Range(0, 100); | ||
} | ||
|
||
if (GUILayout.Button("clear")) | ||
{ | ||
mDictionary.Clear(); | ||
} | ||
} | ||
|
||
GUILayout.EndVertical(); | ||
|
||
|
||
|
||
|
||
if (mKeyToDelete.IsNotNullAndEmpty()) | ||
{ | ||
mDictionary.Remove(mKeyToDelete); | ||
mKeyToDelete = null; | ||
} | ||
} | ||
} | ||
} | ||
|
||
``` | ||
|
||
运行结果如下: | ||
![178a650f-97ee-44de-8f5c-447a853cdb6b](https://file.liangxiegame.com/178a650f-97ee-44de-8f5c-447a853cdb6b.gif) | ||
|
||
输出结果如下: | ||
![b8a5eb15-42cc-4c2d-9e5e-dff54e2a10e2](https://file.liangxiegame.com/b8a5eb15-42cc-4c2d-9e5e-dff54e2a10e2.png) | ||
|
||
本文由 QFramework 教程年会员赞助,地址:[https://www.gamepixedu.com/goods/show/55](https://www.gamepixedu.com/goods/show/55) | ||
|
||
* QFramework 主页:[qframework.cn](https://qframework.cn) | ||
* QFramework 交流群: 623597263 | ||
* QFramework Github 地址: <https://github.com/liangxiegame/qframework> | ||
* QFramework Gitee 地址:<https://gitee.com/liangxiegame/QFramework> |
3 changes: 3 additions & 0 deletions
3
...e/Editor/Resources/EditorGuideline/5. v1.0 之后新增功能/20240919. 新增 BindableDictionary.md.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.