175 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			175 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C#
		
	
	
	
|  | using UnityEngine; | |||
|  | using System.Collections.Generic; | |||
|  | using System; | |||
|  | using System.Threading; | |||
|  | using System.Linq; | |||
|  | 
 | |||
|  | namespace EFSDK | |||
|  | { | |||
|  |     public class WLoom : MonoBehaviour | |||
|  |     { | |||
|  |         public static int maxThreads = 8; | |||
|  |         static int numThreads; | |||
|  | 
 | |||
|  |         private static WLoom _current; | |||
|  | 
 | |||
|  |         //private int _count; | |||
|  |         public static WLoom 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<WLoom>(); | |||
|  |                 DontDestroyOnLoad(g); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         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); | |||
|  |                 } | |||
|  |             } | |||
|  |         } | |||
|  |     } | |||
|  | } |