using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace TMPro
{
    /// 
    /// Alternative Action delegate with increased performance when adding or removing delegates.
    /// 
    public class FastAction
    {
        LinkedList delegates = new LinkedList();
        Dictionary> lookup = new Dictionary>();
        public void Add(System.Action rhs)
        {
            if (lookup.ContainsKey(rhs)) return;
            lookup[rhs] = delegates.AddLast(rhs);
        }
        public void Remove(System.Action rhs)
        {
            LinkedListNode node;
            if (lookup.TryGetValue(rhs, out node))
            {
                lookup.Remove(rhs);
                delegates.Remove(node);
            }
        }
        public void Call()
        {
            var node = delegates.First;
            while (node != null)
            {
                node.Value();
                node = node.Next;
            }
        }
    }
    /// 
    /// Alternative Action delegate with increased performance when adding or removing delegates.
    /// 
    /// The parameter of the method that this delegate encapsulates.
    public class FastAction
    {
        LinkedList> delegates = new LinkedList>();
        Dictionary, LinkedListNode>> lookup = new Dictionary, LinkedListNode>>();
        public void Add(System.Action rhs)
        {
            if (lookup.ContainsKey(rhs)) return;
            lookup[rhs] = delegates.AddLast(rhs);
        }
        public void Remove(System.Action rhs)
        {
            LinkedListNode> node;
            if (lookup.TryGetValue(rhs, out node))
            {
                lookup.Remove(rhs);
                delegates.Remove(node);
            }
        }
        public void Call(A a)
        {
            var node = delegates.First;
            while (node != null)
            {
                node.Value(a);
                node = node.Next;
            }
        }
    }
    /// 
    /// Alternative Action delegate with increased performance when adding or removing delegates.
    /// 
    /// The first parameter of the method that this delegate encapsulates.
    /// The second parameter of the method that this delegate encapsulates.
    public class FastAction
    {
        LinkedList> delegates = new LinkedList>();
        Dictionary, LinkedListNode>> lookup = new Dictionary, LinkedListNode>>();
        public void Add(System.Action rhs)
        {
            if (lookup.ContainsKey(rhs)) return;
            lookup[rhs] = delegates.AddLast(rhs);
        }
        public void Remove(System.Action rhs)
        {
            LinkedListNode> node;
            if (lookup.TryGetValue(rhs, out node))
            {
                lookup.Remove(rhs);
                delegates.Remove(node);
            }
        }
        public void Call(A a, B b)
        {
            var node = delegates.First;
            while (node != null)
            {
                node.Value(a, b);
                node = node.Next;
            }
        }
    }
    /// 
    /// Alternative Action delegate with increased performance when adding or removing delegates.
    /// 
    /// The first parameter of the method that this delegate encapsulates.
    /// The second parameter of the method that this delegate encapsulates.
    /// The third parameter of the method that this delegate encapsulates.
    public class FastAction
    {
        LinkedList> delegates = new LinkedList>();
        Dictionary, LinkedListNode>> lookup = new Dictionary, LinkedListNode>>();
        public void Add(System.Action rhs)
        {
            if (lookup.ContainsKey(rhs)) return;
            lookup[rhs] = delegates.AddLast(rhs);
        }
        public void Remove(System.Action rhs)
        {
            LinkedListNode> node;
            if (lookup.TryGetValue(rhs, out node))
            {
                lookup.Remove(rhs);
                delegates.Remove(node);
            }
        }
        public void Call(A a, B b, C c)
        {
            var node = delegates.First;
            while (node != null)
            {
                node.Value(a, b, c);
                node = node.Next;
            }
        }
    }
}