Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Threading;
- using System.Collections.Generic;
- using UnityEngine;
- #region MIT LICENSE
- /*
- License: The MIT License (MIT)
- Copyright (C) 2021 Shannon Rowe
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
- documentation files (the "Software"), to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of
- the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- */
- #endregion
- [RequireComponent (typeof (GameObject))]
- public class Threader : MonoBehaviour
- {
- private const bool UseThreadPoolingDefault = false;
- private static Threader instance;
- private readonly Queue<CallbackInfo> callbackReadyQueue = new Queue<CallbackInfo> ();
- public static void RunAction (Action action, Action callback, bool useThreadPooling = UseThreadPoolingDefault)
- {
- ProcessAction (action, callback, useThreadPooling);
- }
- public static void RunAction (Action<object> action, Action callback, object actionParam, bool useThreadPooling = UseThreadPoolingDefault)
- {
- ProcessAction (() => action (actionParam), callback, useThreadPooling);
- }
- public static void RunAction (Action<object, object> action, Action callback, object actionParam1, object actionParam2, bool useThreadPooling = UseThreadPoolingDefault)
- {
- ProcessAction (() => action (actionParam1, actionParam2), callback, useThreadPooling);
- }
- public static void RunAction (Action<object, object, object> action, Action callback, object actionParam1, object actionParam2, object actionParam3, bool useThreadPooling = UseThreadPoolingDefault)
- {
- ProcessAction (() => action (actionParam1, actionParam2, actionParam3), callback, useThreadPooling);
- }
- public static void RunActionParams (Action<object []> action, Action callback, bool useThreadPooling, params object [] actionParams)
- {
- ProcessAction (() => action (actionParams), callback, useThreadPooling);
- }
- public static void RunFunc (Func<object> func, Action<object> callback, bool useThreadPooling = UseThreadPoolingDefault)
- {
- ProcessFunc (func, callback, useThreadPooling);
- }
- public static void RunFunc (Func<object, object> func, Action<object> callback, object funcParam, bool useThreadPooling = UseThreadPoolingDefault)
- {
- ProcessFunc (() => func (funcParam), callback, useThreadPooling);
- }
- public static void RunFunc (Func<object, object, object> func, Action<object> callback, object funcParam1, object funcParam2, bool useThreadPooling = UseThreadPoolingDefault)
- {
- ProcessFunc (() => func (funcParam1, funcParam2), callback, useThreadPooling);
- }
- public static void RunFunc (Func<object, object, object, object> func, Action<object> callback, object funcParam1, object funcParam2, object funcParam3, bool useThreadPooling = UseThreadPoolingDefault)
- {
- ProcessFunc (() => func (funcParam1, funcParam2, funcParam3), callback, useThreadPooling);
- }
- public static void RunFuncParams (Func<object [], object> func, Action<object> callback, bool useThreadPooling, params object [] funcParams)
- {
- ProcessFunc (() => func (funcParams), callback, useThreadPooling);
- }
- private static void ProcessAction (Action action, Action callback, bool useThreadPooling)
- {
- if (useThreadPooling)
- {
- ThreadPool.QueueUserWorkItem (delegate { instance.WaitForActionToComplete (action, callback); });
- }
- else
- {
- ThreadStart threadStart = delegate { instance.WaitForActionToComplete (action, callback); };
- new Thread (threadStart).Start ();
- }
- }
- private static void ProcessFunc (Func<object> func, Action<object> callback, bool useThreadPooling)
- {
- if (useThreadPooling)
- {
- ThreadPool.QueueUserWorkItem (delegate { instance.WaitForFuncToComplete (func, callback); });
- }
- else
- {
- ThreadStart threadStart = delegate { instance.WaitForFuncToComplete (func, callback); };
- new Thread (threadStart).Start ();
- }
- }
- private void WaitForActionToComplete (Action action, Action callback)
- {
- action ();
- if (callback == null)
- {
- return;
- }
- lock (callbackReadyQueue)
- {
- callbackReadyQueue.Enqueue (new CallbackInfo (callback));
- }
- }
- private void WaitForFuncToComplete (Func<object> func, Action<object> callback)
- {
- object funcResultDataToPassToCallback = func ();
- if (callback == null)
- {
- return;
- }
- lock (callbackReadyQueue)
- {
- callbackReadyQueue.Enqueue (new CallbackInfo (callback, funcResultDataToPassToCallback));
- }
- }
- private struct CallbackInfo
- {
- public readonly Action callbackNoData;
- public readonly Action<object> callbackWithData;
- public readonly object inputData;
- public readonly bool hasData;
- public CallbackInfo (Action callback)
- {
- callbackNoData = callback;
- callbackWithData = null;
- inputData = null;
- hasData = false;
- }
- public CallbackInfo (Action<object> callback, object inputData)
- {
- callbackNoData = null;
- callbackWithData = callback;
- this.inputData = inputData;
- hasData = true;
- }
- }
- private void Awake ()
- {
- instance = this;
- }
- private void Update ()
- {
- lock (callbackReadyQueue)
- {
- if (callbackReadyQueue.Count == 0)
- {
- return;
- }
- for (int i = 0; i < callbackReadyQueue.Count; i++)
- {
- CallbackInfo callbackInfo = callbackReadyQueue.Dequeue ();
- if (callbackInfo.hasData)
- {
- callbackInfo.callbackWithData (callbackInfo.inputData);
- }
- else
- {
- callbackInfo.callbackNoData ();
- }
- }
- }
- }
- }
- /* TESTING EXAMPLES
- private Vector2 [] actionOneStorage;
- private void TestThreading ()
- {
- int reps = 3;
- Threader.RunAction (TestActionOneParam, CallbackActionOneParam, reps);
- Threader.RunFunc (TestFuncTwoParams, CallbackFuncTwoParams, 5000, reps);
- }
- private void TestActionOneParam (object numreps)
- {
- Debug.LogWarning ("Running TestActionOneParam");
- Vector2 [] ret = new Vector2 [(int) numreps];
- for (int i = 0; i < (int) numreps; i++)
- {
- ret [i] = new Vector2 (i, i);
- }
- actionOneStorage = ret;
- }
- private void CallbackActionOneParam ()
- {
- Debug.LogWarning ("Running CallbackActionOneParam");
- foreach (Vector2 i in (Vector2 []) actionOneStorage)
- {
- Debug.Log ("CallbackActionOneParam: " + i);
- }
- }
- private object TestFuncTwoParams (object prefix, object numreps)
- {
- Debug.LogWarning ("Running TestFuncTwoParams");
- Vector2 [] ret = new Vector2 [(int) numreps];
- for (int i = 0; i < (int) numreps; i++)
- {
- ret [i] = new Vector2 (i + (int) prefix, i + (int) prefix);
- }
- return ret;
- }
- private void CallbackFuncTwoParams (object data)
- {
- Debug.LogWarning ("Running CallbackFuncTwoParams");
- Vector2 [] ret = (Vector2 []) data;
- foreach (Vector2 i in ret)
- {
- Debug.Log ("CallbackFuncTwoParams: " + i);
- }
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement