Doris232 发表于 2023-1-12 18:56

Unity前缀树红点系统设计

本文借助前缀树结构设计,借助事件触发机制,可有效应付复杂的红点系统设计,满足性能需求。
先看下红点前缀树结构图


如图:当有事件更新红点时,会一级级向上更新父节点。
代码层借助命名key中"/",作为分隔符,创建层级节点
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RedDotManager
{
    private static RedDotManager _instance;
    public static RedDotManager Instance
    {
      get
      {
            if(_instance == null)
                _instance = new RedDotManager();
            return _instance;
      }
    }

    private RedDotNode rootNode = new RedDotNode(null);
    private Dictionary<string, RedDotNode> _allNodes = new Dictionary<string, RedDotNode>();

    //以"/"作为分隔符
    public void AddListen(string key, Action<int> callBack)
    {
      var splitKeys = key.Split("/");
      RedDotNode curNode = rootNode;
      foreach (var splitKey in splitKeys)
      {
            curNode = curNode.GetOrAddChild(splitKey);
      }

      curNode.AddListen(callBack);
      _allNodes.Add(key, curNode);
    }

    public void RemoveListen(string key)
    {
      if (_allNodes.TryGetValue(key, out RedDotNode node))
      {
            node.Destroy();
            _allNodes.Remove(key);
      }
    }

    public RedDotNode GetNode(string key)
    {
      return _allNodes;
    }
}Node节点
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RedDotNode
{
    private Dictionary<string, RedDotNode> _nodes = new Dictionary<string, RedDotNode>();
    private RedDotNode _parentNode;
    private int _count;
    private Action<int> _changeCallback;
    public RedDotNode(RedDotNode parent)
    {
      _parentNode = parent;
    }

    public void AddListen(Action<int> callback)
    {
      _changeCallback += callback;
    }

    public void RemoteListen(Action<int> callback)
    {
      _changeCallback -= callback;
    }

    public RedDotNode GetOrAddChild(string key)
    {
      if (_nodes.TryGetValue(key, out RedDotNode node))
      {
            return node;
      }
      var newNode = new RedDotNode(this);
      _nodes.Add(key, newNode);
      return newNode;
    }

    public void ValueIncre(int incre)
    {
      _count += incre;
      _changeCallback?.Invoke(_count);
      _parentNode?.ValueIncre(incre);
    }

    public int GetCount()
    {
      return _count;
    }

    public void Destroy()
    {
      _changeCallback = null;
    }
}
页: [1]
查看完整版本: Unity前缀树红点系统设计