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);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |