132 lines
No EOL
4.5 KiB
C#
132 lines
No EOL
4.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
using Network;
|
|
|
|
using UnityEngine;
|
|
|
|
namespace ResourceLoading
|
|
{
|
|
|
|
internal class Loader
|
|
{
|
|
private LoadingCoroutineFactory _loaderFactory = new LoadingCoroutineFactory();
|
|
|
|
private Queue<LoadingResourceData> _pendingLoading = new Queue<LoadingResourceData>();
|
|
private List<UnloadingResourceData> _pendingUnloading = new List<UnloadingResourceData>();
|
|
|
|
private ConsoleServer _resourceServer = null;
|
|
|
|
private const int UNLOAD_DELAY = 100; // in frames
|
|
|
|
private Queue<LoadWorker> _idleLoadWorkers = new Queue<LoadWorker>();
|
|
private List<LoadWorker> _busyLoadWorkers = new List<LoadWorker>();
|
|
|
|
|
|
internal void LoadResource(Resource resource)
|
|
{
|
|
resource.State = Resource.EState.Loading;
|
|
ILoadingCoroutine loader = _loaderFactory.NewLoadingCoroutineFromType(resource.Type, resource.URI);
|
|
LoadingResourceData loadingData = new LoadingResourceData { _resource = resource, _loadingCoroutine = loader, _useDiskCache = true };
|
|
_pendingLoading.Enqueue(loadingData);
|
|
}
|
|
|
|
internal void UnloadResource(Resource resource)
|
|
{
|
|
resource.State = Resource.EState.Unloading;
|
|
UnloadingResourceData data = new UnloadingResourceData{ _resource = resource, _unloadDelay = UNLOAD_DELAY };
|
|
_pendingUnloading.Add(data);
|
|
}
|
|
|
|
internal void AddWorker(LoadWorker loadWorker)
|
|
{
|
|
_idleLoadWorkers.Enqueue(loadWorker);
|
|
}
|
|
|
|
internal void Update()
|
|
{
|
|
ProcessLoading();
|
|
ProcessUnloading();
|
|
}
|
|
|
|
internal ConsoleServer ResourceServer
|
|
{
|
|
get { return _resourceServer; }
|
|
set { _resourceServer = value; }
|
|
}
|
|
|
|
private void ProcessLoading()
|
|
{
|
|
// process busy workers
|
|
var finished = _busyLoadWorkers.Where(worker => worker.Loader.IsDone).ToList();
|
|
foreach(var worker in finished)
|
|
{
|
|
worker.LoadingResource.UnityResource = worker.Loader.Resource;
|
|
if (worker.LoadingResource.UnityResource != null)
|
|
{
|
|
worker.LoadingResource.State = Resource.EState.Idle;
|
|
}
|
|
else
|
|
{
|
|
worker.LoadingResource.State = Resource.EState.Error;
|
|
}
|
|
worker.Reset();
|
|
_busyLoadWorkers.Remove(worker);
|
|
_idleLoadWorkers.Enqueue(worker);
|
|
}
|
|
finished.Clear();
|
|
|
|
// start new jobs if possible
|
|
while (_pendingLoading.Count > 0 && _idleLoadWorkers.Count > 0)
|
|
{
|
|
var loadingData = _pendingLoading.Dequeue();
|
|
var worker = _idleLoadWorkers.Dequeue();
|
|
worker.Load(loadingData._resource, _resourceServer, loadingData._loadingCoroutine, loadingData._useDiskCache);
|
|
_busyLoadWorkers.Add(worker);
|
|
}
|
|
}
|
|
|
|
private void ProcessUnloading()
|
|
{
|
|
// update unloading list
|
|
foreach(var item in _pendingUnloading)
|
|
{
|
|
if (item._resource.LoadCount == 0)
|
|
{
|
|
--item._unloadDelay;
|
|
// delay expired?
|
|
if (item._unloadDelay <= 0)
|
|
{
|
|
if (item._resource.URI.StartsWith("local://"))
|
|
UnityEngine.Resources.UnloadAsset(item._resource.UnityResource);
|
|
else
|
|
Object.Destroy(item._resource.UnityResource);
|
|
item._resource.UnityResource = null;
|
|
item._resource.State = Resource.EState.Idle;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// while unloading, someone requested loading, pass to idle state
|
|
item._resource.State = Resource.EState.Idle;
|
|
}
|
|
}
|
|
// remove from unloading all for which are not unloading anymore or unload delay has expired
|
|
_pendingUnloading.RemoveAll(item => (item._resource.LoadCount != 0 || item._unloadDelay <= 0));
|
|
}
|
|
|
|
private class LoadingResourceData
|
|
{
|
|
public Resource _resource;
|
|
public ILoadingCoroutine _loadingCoroutine;
|
|
public bool _useDiskCache;
|
|
}
|
|
|
|
private class UnloadingResourceData
|
|
{
|
|
public Resource _resource;
|
|
public int _unloadDelay;
|
|
}
|
|
}
|
|
|
|
} // namespace JDCompanionApp.Resources |