175 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			175 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
|  | using UnityEngine; | |||
|  | using System.Collections; | |||
|  | using System.Collections.Generic; | |||
|  | using System; | |||
|  | using System.Threading; | |||
|  | using System.Linq; | |||
|  | 
 | |||
|  | public class Loom : MonoBehaviour | |||
|  | { | |||
|  |     public static int maxThreads = 8; | |||
|  |     static int numThreads; | |||
|  | 
 | |||
|  |     private static Loom _current; | |||
|  |     //private int _count; | |||
|  |     public static Loom Current | |||
|  |     { | |||
|  |         get | |||
|  |         { | |||
|  |             Initialize(); | |||
|  |             return _current; | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     void Awake() | |||
|  |     { | |||
|  |         _current = this; | |||
|  |         initialized = true; | |||
|  |     } | |||
|  | 
 | |||
|  |     static bool initialized; | |||
|  | 
 | |||
|  |     public static void Initialize() | |||
|  |     { | |||
|  |         if (!initialized) | |||
|  |         { | |||
|  | 
 | |||
|  |             if (!Application.isPlaying) | |||
|  |                 return; | |||
|  |             initialized = true; | |||
|  |             var g = new GameObject("Loom"); | |||
|  |             _current = g.AddComponent<Loom>(); | |||
|  | #if !ARTIST_BUILD | |||
|  |             UnityEngine.Object.DontDestroyOnLoad(g); | |||
|  | #endif | |||
|  |         } | |||
|  | 
 | |||
|  |     } | |||
|  |     public struct NoDelayedQueueItem | |||
|  |     { | |||
|  |         public Action<object> action; | |||
|  |         public object param; | |||
|  |     } | |||
|  | 
 | |||
|  |     private List<NoDelayedQueueItem> _actions = new List<NoDelayedQueueItem>(); | |||
|  |     public struct DelayedQueueItem | |||
|  |     { | |||
|  |         public float time; | |||
|  |         public Action<object> action; | |||
|  |         public object param; | |||
|  |     } | |||
|  |     private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>(); | |||
|  | 
 | |||
|  |     List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>(); | |||
|  | 
 | |||
|  |     public static void QueueOnMainThread(Action<object> taction, object tparam) | |||
|  |     { | |||
|  |         QueueOnMainThread(taction, tparam, 0f); | |||
|  |     } | |||
|  |     public static void QueueOnMainThread(Action<object> taction, object tparam, float time) | |||
|  |     { | |||
|  |         if (time != 0) | |||
|  |         { | |||
|  |             lock (Current._delayed) | |||
|  |             { | |||
|  |                 Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = taction, param = tparam }); | |||
|  |             } | |||
|  |         } | |||
|  |         else | |||
|  |         { | |||
|  |             lock (Current._actions) | |||
|  |             { | |||
|  |                 Current._actions.Add(new NoDelayedQueueItem { action = taction, param = tparam }); | |||
|  |             } | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     public static Thread RunAsync(Action a) | |||
|  |     { | |||
|  |         Initialize(); | |||
|  |         while (numThreads >= maxThreads) | |||
|  |         { | |||
|  |             Thread.Sleep(100); | |||
|  |         } | |||
|  |         Interlocked.Increment(ref numThreads); | |||
|  |         ThreadPool.QueueUserWorkItem(RunAction, a); | |||
|  |         return null; | |||
|  |     } | |||
|  | 
 | |||
|  |     private static void RunAction(object action) | |||
|  |     { | |||
|  |         try | |||
|  |         { | |||
|  |             ((Action)action)(); | |||
|  |         } | |||
|  |         catch | |||
|  |         { | |||
|  |         } | |||
|  |         finally | |||
|  |         { | |||
|  |             Interlocked.Decrement(ref numThreads); | |||
|  |         } | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  |     void OnDisable() | |||
|  |     { | |||
|  |         if (_current == this) | |||
|  |         { | |||
|  | 
 | |||
|  |             _current = null; | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     public void ToukaGamesInit() | |||
|  |     { | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |     // Use this for initialization | |||
|  |     void Start() | |||
|  |     { | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |     List<NoDelayedQueueItem> _currentActions = new List<NoDelayedQueueItem>(); | |||
|  | 
 | |||
|  |     // Update is called once per frame | |||
|  |     void Update() | |||
|  |     { | |||
|  |         if (_actions.Count > 0) | |||
|  |         { | |||
|  |             lock (_actions) | |||
|  |             { | |||
|  |                 _currentActions.Clear(); | |||
|  |                 _currentActions.AddRange(_actions); | |||
|  |                 _actions.Clear(); | |||
|  |             } | |||
|  |             for (int i = 0; i < _currentActions.Count; i++) | |||
|  |             { | |||
|  |                 _currentActions[i].action(_currentActions[i].param); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         if (_delayed.Count > 0) | |||
|  |         { | |||
|  |             lock (_delayed) | |||
|  |             { | |||
|  |                 _currentDelayed.Clear(); | |||
|  |                 _currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time)); | |||
|  |                 for (int i = 0; i < _currentDelayed.Count; i++) | |||
|  |                 { | |||
|  |                     _delayed.Remove(_currentDelayed[i]); | |||
|  |                 } | |||
|  |             } | |||
|  | 
 | |||
|  |             for (int i = 0; i < _currentDelayed.Count; i++) | |||
|  |             { | |||
|  |                 _currentDelayed[i].action(_currentDelayed[i].param); | |||
|  |             } | |||
|  |         } | |||
|  |     } | |||
|  | } |