| 
									
										
										
										
											2025-08-31 01:11:05 +00:00
										 |  |  | using System; | 
					
						
							|  |  |  | using System.Collections; | 
					
						
							|  |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  | using System.Linq; | 
					
						
							|  |  |  | using System.Threading; | 
					
						
							|  |  |  | using UnityEngine; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-01 10:32:50 +00:00
										 |  |  | namespace WZ | 
					
						
							| 
									
										
										
										
											2025-08-31 01:11:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     public class ThreadUtils : MonoBehaviour | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         public static int maxThreads = 8; | 
					
						
							|  |  |  |         static int numThreads; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static ThreadUtils _current; | 
					
						
							|  |  |  |         //private int _count; | 
					
						
							|  |  |  |         public static ThreadUtils 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("ThreadUtils"); | 
					
						
							|  |  |  |                 _current = g.AddComponent<ThreadUtils>(); | 
					
						
							|  |  |  | #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); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }  | 
					
						
							|  |  |  | } |