定义常量:
public class RedPointConst
{
public const string main = "Main";
public const string mail = "Main.Mail";
public const string mailSystem = "Main.Mail.System";
public const string mailTeam = "Main.Mail.Team";
public const string mailAlliance = "Main.Mail.Alliance";
}
节点:
using System.Collections.Generic;
using UnityEngine;
public class RedPointNode
{
public string nodeName;
public int pointNum = 0;
public RedPointNode parent = null;
public Dictionary<string, RedPointNode> dicChilds = new Dictionary<string, RedPointNode>();
public RedPointSystem.OnPointNumChange numChangeFunc;
public void SetRedPointNum(int rpNum)
{
if (dicChilds.Count > 0)
{
Debug.LogError("only can set leaf node");
return;
}
pointNum = rpNum;
NotifyPointNumChange();
if (parent != null)
{
parent.ChangeRedPointNum();
}
}
public void NotifyPointNumChange()
{
if (numChangeFunc != null)
{
numChangeFunc.Invoke(this);
}
}
public void ChangeRedPointNum()
{
int num = 0;
foreach (var node in dicChilds.Values)
{
num += node.pointNum;
}
if (num != pointNum)
{
pointNum = num;
NotifyPointNumChange();
}
//--
if (parent != null)
{
parent.ChangeRedPointNum();
}
}
}
系统:
using System.Collections.Generic;
using UnityEngine;
public class RedPointSystem
{
public delegate void OnPointNumChange(RedPointNode node);
RedPointNode mRootNode;
static List<string> lstRedPointTreeList = new List<string>()
{
RedPointConst.main,
RedPointConst.mail,
RedPointConst.mailSystem,
RedPointConst.mailTeam,
RedPointConst.mailAlliance,
};
public void InitRedPointTreeNode()
{
mRootNode = new RedPointNode();
mRootNode.nodeName = RedPointConst.main;
//--
mRootNode.numChangeFunc = (node) =>
{ Debug.Log(node.nodeName + " rpNum change num = :" + node.pointNum); };
foreach (var s in lstRedPointTreeList)
{
var node = mRootNode;
var treeNodeAy = s.Split('.');
if (treeNodeAy[0] != mRootNode.nodeName)
{
Debug.LogError("redpointtree root node error :" + treeNodeAy[0]);
continue;
}
if (treeNodeAy.Length > 1)
{
for (int i = 1; i < treeNodeAy.Length; i++)
{
if (!node.dicChilds.ContainsKey(treeNodeAy[i]))
{
node.dicChilds.Add(treeNodeAy[i], new RedPointNode());
}
//--
node.dicChilds[treeNodeAy[i]].nodeName = node.nodeName + "." + treeNodeAy[i];
node.dicChilds[treeNodeAy[i]].parent = node;
node = node.dicChilds[treeNodeAy[i]];
}
}
}
}
public void SetRedPointNodeCallback(string strNode, OnPointNumChange callBack)
{
var nodeList = strNode.Split('.');
if (nodeList.Length == 1)
{
if (nodeList[0] != RedPointConst.main)
{
Debug.LogError("get wrong root node , current is :" + nodeList[0]);
return;
}
}
var node = mRootNode;
for (int i = 1; i < nodeList.Length; i++)
{
if (!node.dicChilds.ContainsKey(nodeList[i]))
{
Debug.LogError("does not contains child node :" + nodeList[i]);
return;
}
node = node.dicChilds[nodeList[i]];
if (i == nodeList.Length - 1)
{
node.numChangeFunc = callBack;
return;
}
}
}
public void SetInvoke(string strNode, int rpNum)
{
var nodeList = strNode.Split('.');
if (nodeList.Length == 1)
{
if (nodeList[0] != RedPointConst.main)
{
Debug.LogError("get wrong root node , current is :" + nodeList[0]);
return;
}
}
var node = mRootNode;
for (int i = 1; i < nodeList.Length; i++)
{
if (!node.dicChilds.ContainsKey(nodeList[i]))
{
Debug.LogError("does not contains child node :" + nodeList[i]);
return;
}
node = node.dicChilds[nodeList[i]];
if (i == nodeList.Length - 1)
{
node.SetRedPointNum(rpNum);
}
}
}
}
测试:
using UnityEngine;
public class RedPointTest : MonoBehaviour
{
private void Start()
{
RedPointSystem rps = new RedPointSystem();
rps.InitRedPointTreeNode();
rps.SetRedPointNodeCallback(RedPointConst.mail, XXXCallBack);
rps.SetRedPointNodeCallback(RedPointConst.mailSystem, XXXCallBack);
rps.SetRedPointNodeCallback(RedPointConst.mailTeam, XXXCallBack);
rps.SetRedPointNodeCallback(RedPointConst.mailAlliance, XXXCallBack);
rps.SetInvoke(RedPointConst.mailSystem, 3);
rps.SetInvoke(RedPointConst.mailTeam, 2);
rps.SetInvoke(RedPointConst.mailAlliance, 2);
}
private void XXXCallBack(RedPointNode node)
{
Debug.Log(node.nodeName + " rpNum change num = :" + node.pointNum);
}
}
结果:
参考 侑虎科技的微信公众号 文章。