美文网首页工具类
Unity 在开启的多线程里面调用主线程的东西

Unity 在开启的多线程里面调用主线程的东西

作者: 玄策丶 | 来源:发表于2022-12-05 09:52 被阅读0次
/*****************************
 * 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 在开启的多线程里面调用主线程的东西

  • 实现Swift的委托(Delegate)的三种方式

    在多线程编程中,常常会遇到这样一种场景:主界面开启一个新线程,在新线程执行过程中,需要调用主界面的某个方法(比如更...

  • 多线程

    1、你理解的多线程(什么是多线程、多线程的原理、多线程的优缺点)? 首先多线程就是在一个进程里面开启了多条线程同时...

  • [Unity 3d] 老瓶新酒,看我基于PlayerLoopSy

    Loom :在 Unity 多线程编程中实现线程间的数据同步,避免非主线程直接操作 Unity 对象。在本文,笔者...

  • 3-ndk学习之jni基础篇(3)

    jni多线程操作 这里的效果是在jni中开启子线程,然后在子线程直接调用Activity的方法jni中,jvm是跨...

  • 多线程

    多线程 多线程 一个进程里面可以开启多条线程,每条线程可以并行(同时)执行不同的任务比如同时开启三条线程分别下载三...

  • Unity多线程(C#)

    前言 在这之前,有很多人在质疑Unity支不支持多线程,事实上Unity是支持多线程的。而提到多线程就要提到Uni...

  • python多线程和定时任务

    python多线程或定时任务 1. 定时任务 下图是上述代码的输出: 2. 多线程 在主函数中调用class就可以...

  • Unity多线程管理

    Unity多线程管理 游戏中我们有许多地方还是有需求要开启多线程,例如下载文件,解压文件等操作,我们需要在Unit...

  • ArrayList多线程调用add()可能出现的问题

    ArrayList多线程调用add()可能出现的问题 一 ArrayList在多线程调用Add()添加元素时的下...

网友评论

    本文标题:Unity 在开启的多线程里面调用主线程的东西

    本文链接:https://www.haomeiwen.com/subject/jwletdtx.html