215 lines
5.7 KiB
C#
215 lines
5.7 KiB
C#
using Assets.Core;
|
|
using Assets.Scenes.Ride.Scripts;
|
|
using Assets.Scripts.Apis.Models;
|
|
using Cysharp.Threading.Tasks;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
|
|
/// <summary>
|
|
/// 异步线程更新ui工具类
|
|
/// </summary>
|
|
public class Loom : MonoBehaviour
|
|
{
|
|
public static int maxThreads = 8;
|
|
static int numThreads;
|
|
|
|
private static Loom _current;
|
|
public static Loom Current
|
|
{
|
|
get
|
|
{
|
|
Initialize();
|
|
return _current;
|
|
}
|
|
}
|
|
//####去除Awake
|
|
// void Awake()
|
|
// {
|
|
// _current = this;
|
|
// initialized = true;
|
|
// }
|
|
|
|
static bool initialized;
|
|
|
|
//####作为初始化方法自己调用,可在初始化场景调用一次即可
|
|
public static void Initialize()
|
|
{
|
|
if (!initialized)
|
|
{
|
|
|
|
if (!Application.isPlaying)
|
|
return;
|
|
initialized = true;
|
|
GameObject g = new GameObject("Loom");
|
|
//####永不销毁
|
|
DontDestroyOnLoad(g);
|
|
_current = g.AddComponent<Loom>();
|
|
MapUDPService.Init();
|
|
MapUDPService.Send(0, App.CurrentUser.Id, new double[] { -1d, -1d }, competitionId: 0);
|
|
}
|
|
}
|
|
|
|
private List<Action> _actions = new List<Action>();
|
|
public struct DelayedQueueItem
|
|
{
|
|
public float time;
|
|
public Action action;
|
|
}
|
|
private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
|
|
|
|
List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>();
|
|
|
|
public static void QueueOnMainThread(Action action)
|
|
{
|
|
QueueOnMainThread(action, 0f);
|
|
}
|
|
public static void QueueOnMainThread(Action action, float time)
|
|
{
|
|
if (time != 0)
|
|
{
|
|
if (Current != null)
|
|
{
|
|
lock (Current._delayed)
|
|
{
|
|
Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action });
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Current != null)
|
|
{
|
|
lock (Current._actions)
|
|
{
|
|
Current._actions.Add(action);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Thread RunAsync(Action a)
|
|
{
|
|
Initialize();
|
|
while (numThreads >= maxThreads)
|
|
{
|
|
Thread.Sleep(1);
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
|
|
List<Action> _currentActions = new List<Action>();
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
lock (_actions)
|
|
{
|
|
_currentActions.Clear();
|
|
_currentActions.AddRange(_actions);
|
|
_actions.Clear();
|
|
}
|
|
foreach (var a in _currentActions)
|
|
{
|
|
a();
|
|
}
|
|
lock (_delayed)
|
|
{
|
|
_currentDelayed.Clear();
|
|
_currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time));
|
|
foreach (var item in _currentDelayed)
|
|
_delayed.Remove(item);
|
|
}
|
|
foreach (var delayed in _currentDelayed)
|
|
{
|
|
delayed.action();
|
|
}
|
|
|
|
}
|
|
|
|
public static void Dispose()
|
|
{
|
|
if (_current != null)
|
|
{
|
|
initialized = false;
|
|
DestroyImmediate(_current.gameObject);
|
|
_current = null;
|
|
}
|
|
}
|
|
|
|
public static Dictionary<string, DownloadInfo> DownloadStack = new Dictionary<string, DownloadInfo>();
|
|
|
|
public static async Task DownloadLoadARDataAndVideo(MapRoute route,IProgress<float> progress)
|
|
{
|
|
DownloadStack.Add(route.FileName, new DownloadInfo(route.FileName,route.Name,0, route.Url));
|
|
|
|
var path = PFConstants.VideoFolder;
|
|
var localPath = PFConstants.ARFolder;
|
|
var arDataPath = route.ARConfig;
|
|
var videoRoute = route.VideoRoute;
|
|
var cancelToken = new CancellationTokenSource();
|
|
var dataPath = $"{localPath}/{route.Id}";
|
|
|
|
Helper.CreateDirectoryIfNotExsit(dataPath);
|
|
Helper.CreateDirectoryIfNotExsit(dataPath);
|
|
|
|
await Loom.DownloadToFileAsync(arDataPath, $"{dataPath}/{route.Id}.json");
|
|
await Loom.DownloadToFileAsync(videoRoute, $"{dataPath}/route-{route.Id}.json");
|
|
await Loom.DownloadToFileAsync(route.Url, $"{path}/{route.FileName}", progress, cancelToken);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 下载文件到本地(持续存入磁盘减少内存占用)
|
|
/// </summary>
|
|
/// <param name="downloadUrl">文件连接</param>
|
|
/// <param name="fullPath">本地文件全路径</param>
|
|
/// <param name="progress">下载进度</param>
|
|
public static async UniTask<UnityWebRequest> DownloadToFileAsync(string downloadUrl, string fullPath, IProgress<float> progress = null, CancellationTokenSource cancellation = default(CancellationTokenSource))
|
|
{
|
|
var dh = new DownloadHandlerFile(fullPath)
|
|
{
|
|
removeFileOnAbort = true
|
|
};
|
|
|
|
var request = UnityWebRequest.Get(downloadUrl);
|
|
request.method = UnityWebRequest.kHttpVerbGET;
|
|
request.downloadHandler = dh;
|
|
|
|
return await request.SendWebRequest().ToUniTask(progress, PlayerLoopTiming.Update, (cancellation?.Token ?? default(CancellationToken)));
|
|
}
|
|
}
|