Advertisement
chmodseven

Threader

May 13th, 2018 (edited)
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.56 KB | None | 0 0
  1. using System;
  2. using System.Threading;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5.  
  6. #region MIT LICENSE
  7.  
  8. /*
  9.     License: The MIT License (MIT)
  10.     Copyright (C) 2021 Shannon Rowe
  11.    
  12.     Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  13.     documentation files (the "Software"), to deal in the Software without restriction, including without limitation
  14.     the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
  15.     and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  16.  
  17.     The above copyright notice and this permission notice shall be included in all copies or substantial portions of
  18.     the Software.
  19.    
  20.     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  21.     TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22.     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  23.     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24.     DEALINGS IN THE SOFTWARE.
  25. */
  26.  
  27. #endregion
  28. [RequireComponent (typeof (GameObject))]
  29. public class Threader : MonoBehaviour
  30. {
  31.     private const bool UseThreadPoolingDefault = false;
  32.  
  33.     private static Threader instance;
  34.     private readonly Queue<CallbackInfo> callbackReadyQueue = new Queue<CallbackInfo> ();
  35.  
  36.     public static void RunAction (Action action, Action callback, bool useThreadPooling = UseThreadPoolingDefault)
  37.     {
  38.         ProcessAction (action, callback, useThreadPooling);
  39.     }
  40.  
  41.     public static void RunAction (Action<object> action, Action callback, object actionParam, bool useThreadPooling = UseThreadPoolingDefault)
  42.     {
  43.         ProcessAction (() => action (actionParam), callback, useThreadPooling);
  44.     }
  45.  
  46.     public static void RunAction (Action<object, object> action, Action callback, object actionParam1, object actionParam2, bool useThreadPooling = UseThreadPoolingDefault)
  47.     {
  48.         ProcessAction (() => action (actionParam1, actionParam2), callback, useThreadPooling);
  49.     }
  50.  
  51.     public static void RunAction (Action<object, object, object> action, Action callback, object actionParam1, object actionParam2, object actionParam3, bool useThreadPooling = UseThreadPoolingDefault)
  52.     {
  53.         ProcessAction (() => action (actionParam1, actionParam2, actionParam3), callback, useThreadPooling);
  54.     }
  55.  
  56.     public static void RunActionParams (Action<object []> action, Action callback, bool useThreadPooling, params object [] actionParams)
  57.     {
  58.         ProcessAction (() => action (actionParams), callback, useThreadPooling);
  59.     }
  60.  
  61.     public static void RunFunc (Func<object> func, Action<object> callback, bool useThreadPooling = UseThreadPoolingDefault)
  62.     {
  63.         ProcessFunc (func, callback, useThreadPooling);
  64.     }
  65.  
  66.     public static void RunFunc (Func<object, object> func, Action<object> callback, object funcParam, bool useThreadPooling = UseThreadPoolingDefault)
  67.     {
  68.         ProcessFunc (() => func (funcParam), callback, useThreadPooling);
  69.     }
  70.  
  71.     public static void RunFunc (Func<object, object, object> func, Action<object> callback, object funcParam1, object funcParam2, bool useThreadPooling = UseThreadPoolingDefault)
  72.     {
  73.         ProcessFunc (() => func (funcParam1, funcParam2), callback, useThreadPooling);
  74.     }
  75.  
  76.     public static void RunFunc (Func<object, object, object, object> func, Action<object> callback, object funcParam1, object funcParam2, object funcParam3, bool useThreadPooling = UseThreadPoolingDefault)
  77.     {
  78.         ProcessFunc (() => func (funcParam1, funcParam2, funcParam3), callback, useThreadPooling);
  79.     }
  80.  
  81.     public static void RunFuncParams (Func<object [], object> func, Action<object> callback, bool useThreadPooling, params object [] funcParams)
  82.     {
  83.         ProcessFunc (() => func (funcParams), callback, useThreadPooling);
  84.     }
  85.  
  86.     private static void ProcessAction (Action action, Action callback, bool useThreadPooling)
  87.     {
  88.         if (useThreadPooling)
  89.         {
  90.             ThreadPool.QueueUserWorkItem (delegate { instance.WaitForActionToComplete (action, callback); });
  91.         }
  92.         else
  93.         {
  94.             ThreadStart threadStart = delegate { instance.WaitForActionToComplete (action, callback); };
  95.             new Thread (threadStart).Start ();
  96.         }
  97.     }
  98.  
  99.     private static void ProcessFunc (Func<object> func, Action<object> callback, bool useThreadPooling)
  100.     {
  101.         if (useThreadPooling)
  102.         {
  103.             ThreadPool.QueueUserWorkItem (delegate { instance.WaitForFuncToComplete (func, callback); });
  104.         }
  105.         else
  106.         {
  107.             ThreadStart threadStart = delegate { instance.WaitForFuncToComplete (func, callback); };
  108.             new Thread (threadStart).Start ();
  109.         }
  110.     }
  111.  
  112.     private void WaitForActionToComplete (Action action, Action callback)
  113.     {
  114.         action ();
  115.  
  116.         if (callback == null)
  117.         {
  118.             return;
  119.         }
  120.  
  121.         lock (callbackReadyQueue)
  122.         {
  123.             callbackReadyQueue.Enqueue (new CallbackInfo (callback));
  124.         }
  125.     }
  126.  
  127.     private void WaitForFuncToComplete (Func<object> func, Action<object> callback)
  128.     {
  129.         object funcResultDataToPassToCallback = func ();
  130.  
  131.         if (callback == null)
  132.         {
  133.             return;
  134.         }
  135.  
  136.         lock (callbackReadyQueue)
  137.         {
  138.             callbackReadyQueue.Enqueue (new CallbackInfo (callback, funcResultDataToPassToCallback));
  139.         }
  140.     }
  141.  
  142.     private struct CallbackInfo
  143.     {
  144.         public readonly Action callbackNoData;
  145.         public readonly Action<object> callbackWithData;
  146.         public readonly object inputData;
  147.         public readonly bool hasData;
  148.  
  149.         public CallbackInfo (Action callback)
  150.         {
  151.             callbackNoData = callback;
  152.             callbackWithData = null;
  153.             inputData = null;
  154.             hasData = false;
  155.         }
  156.  
  157.         public CallbackInfo (Action<object> callback, object inputData)
  158.         {
  159.             callbackNoData = null;
  160.             callbackWithData = callback;
  161.             this.inputData = inputData;
  162.             hasData = true;
  163.         }
  164.     }
  165.  
  166.     private void Awake ()
  167.     {
  168.         instance = this;
  169.     }
  170.  
  171.     private void Update ()
  172.     {
  173.         lock (callbackReadyQueue)
  174.         {
  175.             if (callbackReadyQueue.Count == 0)
  176.             {
  177.                 return;
  178.             }
  179.  
  180.             for (int i = 0; i < callbackReadyQueue.Count; i++)
  181.             {
  182.                 CallbackInfo callbackInfo = callbackReadyQueue.Dequeue ();
  183.                 if (callbackInfo.hasData)
  184.                 {
  185.                     callbackInfo.callbackWithData (callbackInfo.inputData);
  186.                 }
  187.                 else
  188.                 {
  189.                     callbackInfo.callbackNoData ();
  190.                 }
  191.             }
  192.         }
  193.     }
  194. }
  195.  
  196.  
  197. /* TESTING EXAMPLES
  198.  
  199.     private Vector2 [] actionOneStorage;
  200.  
  201.     private void TestThreading ()
  202.     {
  203.         int reps = 3;
  204.         Threader.RunAction (TestActionOneParam, CallbackActionOneParam, reps);
  205.         Threader.RunFunc (TestFuncTwoParams, CallbackFuncTwoParams, 5000, reps);
  206.     }
  207.  
  208.     private void TestActionOneParam (object numreps)
  209.     {
  210.         Debug.LogWarning ("Running TestActionOneParam");
  211.         Vector2 [] ret = new Vector2 [(int) numreps];
  212.         for (int i = 0; i < (int) numreps; i++)
  213.         {
  214.             ret [i] = new Vector2 (i, i);
  215.         }
  216.         actionOneStorage = ret;
  217.     }
  218.  
  219.     private void CallbackActionOneParam ()
  220.     {
  221.         Debug.LogWarning ("Running CallbackActionOneParam");
  222.         foreach (Vector2 i in (Vector2 []) actionOneStorage)
  223.         {
  224.             Debug.Log ("CallbackActionOneParam: " + i);
  225.         }
  226.     }
  227.  
  228.     private object TestFuncTwoParams (object prefix, object numreps)
  229.     {
  230.         Debug.LogWarning ("Running TestFuncTwoParams");
  231.         Vector2 [] ret = new Vector2 [(int) numreps];
  232.         for (int i = 0; i < (int) numreps; i++)
  233.         {
  234.             ret [i] = new Vector2 (i + (int) prefix, i + (int) prefix);
  235.         }
  236.         return ret;
  237.     }
  238.  
  239.     private void CallbackFuncTwoParams (object data)
  240.     {
  241.         Debug.LogWarning ("Running CallbackFuncTwoParams");
  242.         Vector2 [] ret = (Vector2 []) data;
  243.         foreach (Vector2 i in ret)
  244.         {
  245.             Debug.Log ("CallbackFuncTwoParams: " + i);
  246.         }
  247.     }
  248.  
  249. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement