Advertisement
zORg_alex

OneTimeEvent

Mar 30th, 2024
778
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.32 KB | Source Code | 0 0
  1. using System;
  2.  
  3. // This initially was my first Chat GPT experiment... I should have done that myself and saved a couple of hours :)
  4.  
  5. /// <summary>
  6. /// An event that supposed to be fired once, and after that any subscription will be fired immediately. <code>
  7. /// private static OneTimeEvent onHadInitialized = new OneTimeEvent();
  8. /// public static event Action OnHadInitialized { add => onHadInitialized += value; remove => onHadInitialized -= value; }
  9. /// </code>
  10. /// </summary>
  11. public class OneTimeEvent
  12. {
  13.     private event Action _event;
  14.     private bool _wasInvoked;
  15.     private static object _staticlock = new object();
  16.     private object _lock = new object();
  17.  
  18.     public bool WasInvoked
  19.     {
  20.         get
  21.         {
  22.             lock (_lock)
  23.             {
  24.                 return _wasInvoked;
  25.             }
  26.         }
  27.     }
  28.  
  29.     public static OneTimeEvent operator +(OneTimeEvent oneTimeEvent, Action handler)
  30.     {
  31.         lock (_staticlock)
  32.         {
  33.             if (oneTimeEvent == null)
  34.             {
  35.                 oneTimeEvent = new OneTimeEvent();
  36.  
  37.                 return Subscribe(oneTimeEvent, handler);
  38.             }
  39.         }
  40.         lock (oneTimeEvent._lock)
  41.         {
  42.             return Subscribe(oneTimeEvent, handler);
  43.         }
  44.  
  45.         static OneTimeEvent Subscribe(OneTimeEvent oneTimeEvent, Action handler)
  46.         {
  47.             if (oneTimeEvent._wasInvoked)
  48.             {
  49.                 handler?.Invoke();
  50.             }
  51.             else
  52.             {
  53.                 oneTimeEvent._event += handler;
  54.             }
  55.             return oneTimeEvent;
  56.         }
  57.     }
  58.     public static OneTimeEvent operator -(OneTimeEvent oneTimeEvent, Action handler)
  59.     {
  60.         lock (_staticlock)
  61.         {
  62.             if (oneTimeEvent == null)
  63.             {
  64.                 oneTimeEvent = new OneTimeEvent();
  65.  
  66.                 return Unsubscribe(oneTimeEvent, handler);
  67.             }
  68.         }
  69.         lock (oneTimeEvent._lock)
  70.         {
  71.             return Unsubscribe(oneTimeEvent, handler);
  72.         }
  73.  
  74.         static OneTimeEvent Unsubscribe(OneTimeEvent oneTimeEvent, Action handler)
  75.         {
  76.             if (oneTimeEvent._wasInvoked)
  77.             {
  78.                 handler?.Invoke();
  79.             }
  80.             else
  81.             {
  82.                 oneTimeEvent._event -= handler;
  83.             }
  84.             return oneTimeEvent;
  85.         }
  86.     }
  87.  
  88.     public void Invoke()
  89.     {
  90.         Action temp;
  91.         lock (_lock)
  92.         {
  93.             if (_wasInvoked)
  94.             {
  95.                 return;
  96.             }
  97.  
  98.             _wasInvoked = true;
  99.             temp = _event;
  100.             _event = null;
  101.         }
  102.             temp?.Invoke();
  103.     }
  104.  
  105.     public IAsyncResult BeginInvoking()
  106.     {
  107.         Action temp;
  108.         lock (_lock)
  109.         {
  110.             if (_wasInvoked)
  111.             {
  112.                 return null;
  113.             }
  114.  
  115.             _wasInvoked = true;
  116.             temp = _event;
  117.             _event = null;
  118.         }
  119.         return temp?.BeginInvoke(temp.EndInvoke, null);
  120.     }
  121. }
  122.  
  123. /// <summary>
  124. /// An event that supposed to be fired once, and after that any subscription will be fired immediately.<para/>
  125. /// Thanks Chat GPT to helping improving it... Although, I should have done that myself and saved a couple of hours
  126. /// </summary>
  127. public class OneTimeEvent<T>
  128. {
  129.     private Action<T> _event;
  130.     private T _arg;
  131.     private bool _wasInvoked;
  132.     private static object _staticlock = new object();
  133.     private object _lock = new object();
  134.  
  135.     public bool WasInvoked
  136.     {
  137.         get
  138.         {
  139.             lock (_lock)
  140.             {
  141.                 return _wasInvoked;
  142.             }
  143.         }
  144.     }
  145.  
  146.     public static OneTimeEvent<T> operator +(OneTimeEvent<T> oneTimeEvent, Action<T> handler)
  147.     {
  148.         lock (_staticlock)
  149.         {
  150.             if (oneTimeEvent == null)
  151.             {
  152.                 oneTimeEvent = new OneTimeEvent<T>();
  153.  
  154.                 return Subscribe(oneTimeEvent, handler);
  155.             }
  156.         }
  157.         lock (oneTimeEvent._lock)
  158.         {
  159.             return Subscribe(oneTimeEvent, handler);
  160.         }
  161.  
  162.         static OneTimeEvent<T> Subscribe(OneTimeEvent<T> oneTimeEvent, Action<T> handler)
  163.         {
  164.             if (oneTimeEvent._wasInvoked)
  165.             {
  166.                 handler?.Invoke(oneTimeEvent._arg);
  167.             }
  168.             else
  169.             {
  170.                 oneTimeEvent._event += handler;
  171.             }
  172.             return oneTimeEvent;
  173.         }
  174.     }
  175.  
  176.     public static OneTimeEvent<T> operator -(OneTimeEvent<T> oneTimeEvent, Action<T> handler)
  177.     {
  178.         lock (_staticlock)
  179.         {
  180.             if (oneTimeEvent == null)
  181.             {
  182.                 oneTimeEvent = new OneTimeEvent<T>();
  183.  
  184.                 return Unsubscribe(oneTimeEvent, handler);
  185.             }
  186.         }
  187.         lock (oneTimeEvent._lock)
  188.         {
  189.             return Unsubscribe(oneTimeEvent, handler);
  190.         }
  191.  
  192.         static OneTimeEvent<T> Unsubscribe(OneTimeEvent<T> oneTimeEvent, Action<T> handler)
  193.         {
  194.             if (oneTimeEvent._wasInvoked)
  195.             {
  196.                 handler?.Invoke(oneTimeEvent._arg);
  197.             }
  198.             else
  199.             {
  200.                 oneTimeEvent._event -= handler;
  201.             }
  202.             return oneTimeEvent;
  203.         }
  204.     }
  205.  
  206.     public void Invoke(T arg)
  207.     {
  208.         Action<T> temp;
  209.         lock (_lock)
  210.         {
  211.             if (_wasInvoked)
  212.             {
  213.                 return;
  214.             }
  215.  
  216.             _wasInvoked = true;
  217.             temp = _event;
  218.             _event = null;
  219.         }
  220.         temp?.Invoke(arg);
  221.     }
  222. }
Tags: Unity Async
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement