/*****************************
* Title:
* Date: 2022.11.01
* Author: 玄策
* UnityVersion: 2019.4.28
* Func: 线程里面不能调用主线程的东西,需要用这个脚本
* 使用方法:在线程里面,将主线程的东西注册到一个Action里面,然后调用这个脚本Loom.QueueOnMainThread(Action action);
*
****************************/
using UnityEngine;
using System.Collections.Generic;
using System;
using System.Threading;
using System.Linq;
public class Loom : MonoBehaviour
{
//是否已经初始化
static bool isInitialized;
private static Loom _ins;
public static Loom ins { get { Initialize(); return _ins; } }
void Awake()
{
_ins = this;
isInitialized = true;
}
//初始化
public static void Initialize()
{
if (!isInitialized)
{
if (!Application.isPlaying)
return;
isInitialized = true;
var obj = new GameObject("Loom");
_ins = obj.AddComponent<Loom>();
DontDestroyOnLoad(obj);
}
}
//单个执行单元(无延迟)
struct NoDelayedQueueItem
{
public Action<object> action;
public object param;
}
//全部执行列表(无延迟)
List<NoDelayedQueueItem> listNoDelayActions = new List<NoDelayedQueueItem>();
//单个执行单元(有延迟)
struct DelayedQueueItem
{
public Action<object> action;
public object param;
public float time;
}
//全部执行列表(有延迟)
List<DelayedQueueItem> listDelayedActions = new List<DelayedQueueItem>();
//加入到主线程执行队列(无延迟)
public static void QueueOnMainThread(Action<object> taction, object param)
{
QueueOnMainThread(taction, param, 0f);
}
//加入到主线程执行队列(有延迟)
public static void QueueOnMainThread(Action<object> action, object param, float time)
{
if (time != 0)
{
lock (ins.listDelayedActions)
{
ins.listDelayedActions.Add(new DelayedQueueItem { time = Time.time + time, action = action, param = param });
}
}
else
{
lock (ins.listNoDelayActions)
{
ins.listNoDelayActions.Add(new NoDelayedQueueItem { action = action, param = param });
}
}
}
//当前执行的无延时函数链
List<NoDelayedQueueItem> currentActions = new List<NoDelayedQueueItem>();
//当前执行的有延时函数链
List<DelayedQueueItem> currentDelayed = new List<DelayedQueueItem>();
void Update()
{
if (listNoDelayActions.Count > 0)
{
lock (listNoDelayActions)
{
currentActions.Clear();
currentActions.AddRange(listNoDelayActions);
listNoDelayActions.Clear();
}
for (int i = 0; i < currentActions.Count; i++)
{
currentActions[i].action(currentActions[i].param);
}
}
if (listDelayedActions.Count > 0)
{
lock (listDelayedActions)
{
currentDelayed.Clear();
currentDelayed.AddRange(listDelayedActions.Where(d => Time.time >= d.time));
for (int i = 0; i < currentDelayed.Count; i++)
{
listDelayedActions.Remove(currentDelayed[i]);
}
}
for (int i = 0; i < currentDelayed.Count; i++)
{
currentDelayed[i].action(currentDelayed[i].param);
}
}
}
void OnDisable()
{
if (_ins == this)
{
_ins = null;
}
}
}
Unity 在开启的多线程里面调用主线程的东西
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 在我们需要频繁地开启子线程执行操作的时候,我们可以采用开启子线程runloop的方式保活子线程,这样避免频繁创建线...
- 本文主要举例说明GCD里的死锁场景,分析造成死锁的原因以及解决方案 在开始说GCD死锁之前,我们先了解一下GCD的...
- 成长记录-连载(三十六) ——我的第一篇五千字长文,说了什么,你一定想不到 并不是不想每天写公众号,而是之前思考怎...