红点


class RedPoint
{
    public string parent_key;
    public string key;
    private RedTree tree;
    public Dictionary<string, RedPoint> children = new Dictionary<string, RedPoint>();
    private int count;
    private bool hasValue = false;

    public RedPoint(string key, string parent_key, RedTree tree)
    {
        this.parent_key = parent_key;
        this.key = key;
        this.tree = tree;
    }

    public int GetCount()
    {
        return hasValue ? count : 0;
    }
    public void AddChild(RedPoint p)
    {
        var p_key = p.key;
        if (children.ContainsKey(p_key))
            return;
        children.Add(p_key, p);
    }

    public bool SetCount(int count)
    {
        if (hasValue && count == this.count) return false;
        this.count = count;
        hasValue = true;
        this.tree.FreshDot(key, count);
        return true;
    }
}
public abstract class RedDot : IDisposable
{
    public string path;
    private RedTree tree;

    public void SetPath(string path)
    {
        this.SetPath(path, GGame.Instance.modules.redTree);  // 一开始 要new 一个红点树过来
    }
    public void SetPath(string path, RedTree tree)
    {
        this.path = path;
        this.tree = tree;
        tree.AddDot(this);
        this.FreshView(this.GetCount());
    }
    public int GetCount() => tree.GetCount(this.path);
    public abstract void FreshView(int count);
    public void Dispose()
    {
        tree.RemoveDot(this);
        FreshView(0);
    }
}

public class RedActiveDot : RedDot
{
    private GameObject gameObject;

    public RedActiveDot(string path, GameObject gameObject) //传入一个红点的配置路径 然后把红点对象传进去
    {
        this.gameObject = gameObject;   //对象赋值
        this.SetPath(path);             //把这个路径传入 父类RedDot 的SetPath 函数
    }

    public override void FreshView(int count)
    {
        UnityEngine.Debug.Log($"{this.path}  {count}");
        this.gameObject.SetActive(count > 0);
    }
}
public partial class RedTree
{
    private Dictionary<string, List<RedDot>> red_dot_map = new Dictionary<string, List<RedDot>>();
    private Dictionary<string, RedPoint> key_map = new Dictionary<string, RedPoint>();
    public void AddDot(RedDot dot)
    {
        var path = dot.path;
        if (!red_dot_map.ContainsKey(path))
            red_dot_map.Add(path, new List<RedDot>());
        red_dot_map[path].Add(dot);
    }
    public void RemoveDot(RedDot dot)
    {
        var path = dot.path;
        if (!red_dot_map.ContainsKey(path))
            return;
        if (!red_dot_map[path].Contains(dot)) return;
        red_dot_map[path].Remove(dot);
    }
    private void FreshDot(string path, int count)
    {
        if (!red_dot_map.ContainsKey(path))
            return;
        foreach (var item in red_dot_map[path])
        {
            item.FreshView(count);
        }
    }


    private RedPoint Find(string key)
    {
        if (key_map.ContainsKey(key))
            return key_map[key];
        return null;
    }

    private RedPoint AddPoint(string parentKey, string key)
    {
        var _new = Find(key);
        if (_new == null)
        {
            _new = new RedPoint(key, parentKey, this);
            key_map.Add(key, _new);
        }
        return _new;
    }

    private void FreshParent(string key)
    {
        if (string.IsNullOrEmpty(key)) return;
        var point = Find(key);
        int sum = 0;
        foreach (var item in point.children.Values)
        {
            sum += item.GetCount();
        }
        if (point.SetCount(sum))
        {
            FreshParent(point.parent_key);
        }
    }
    public void SetCount(string key, int count)
    {
        var point = Find(key);
        if (point == null || point.children.Count > 0) return;
        if (point.SetCount(count))
        {
            FreshParent(point.parent_key);
        }
    }
    public int GetCount(string key)
    {
        var point = Find(key);
        return point == null ? 0 : point.GetCount();
    }




    public void ReadPath(string key, char separator)
    {
        var columns = key.Split(separator);
        RedPoint last = null;
        for (int j = 0; j < columns.Length; j++)
        {
            var _pkey = string.Join(separator.ToString(), columns, 0, j);
            var _key = string.Join(separator.ToString(), columns, 0, j + 1);
            var point = AddPoint(_pkey, _key);
            if (last != null)
                last.AddChild(point);
            last = point;
        }
    }
    public void ClearPath(string key)
    {
        var point = Find(key);
        if (point == null) return;
        key_map.Remove(key);
        foreach (var item in point.children.Keys)
        {
            ClearPath(item);
        }
    }


}