240 lines
6.7 KiB
C#
240 lines
6.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.HLODSystem.Streaming
|
|
{
|
|
public class LoadManager
|
|
{
|
|
#region Singleton
|
|
private static LoadManager s_instance;
|
|
|
|
public static LoadManager Instance
|
|
{
|
|
get
|
|
{
|
|
if (s_instance == null)
|
|
{
|
|
GameObject go = new GameObject("LoadManager");
|
|
s_instance = new LoadManager();
|
|
}
|
|
|
|
return s_instance;
|
|
}
|
|
}
|
|
#endregion
|
|
public abstract class Handle
|
|
{
|
|
|
|
public Handle(HLODControllerBase controller, int id, int level, float distance,
|
|
bool isHighObject,
|
|
Action<Handle> loadDoneCallback)
|
|
{
|
|
m_controller = controller;
|
|
m_id = id;
|
|
m_level = level;
|
|
m_distnace = distance;
|
|
m_isHighObject = isHighObject;
|
|
m_loadDoneCallback = loadDoneCallback;
|
|
}
|
|
|
|
public HLODControllerBase Controller
|
|
{
|
|
get { return m_controller; }
|
|
}
|
|
|
|
public GameObject LoadedObject
|
|
{
|
|
get { return m_loadedObject; }
|
|
}
|
|
public bool IsLoading
|
|
{
|
|
get { return m_isLoading; }
|
|
}
|
|
|
|
public int Id
|
|
{
|
|
get { return m_id; }
|
|
}
|
|
|
|
public int Level
|
|
{
|
|
get { return m_level; }
|
|
}
|
|
|
|
public float Distance
|
|
{
|
|
get { return m_distnace; }
|
|
}
|
|
|
|
|
|
|
|
|
|
protected bool m_isLoading = false;
|
|
protected bool m_isHighObject = false;
|
|
protected GameObject m_loadedObject = null;
|
|
|
|
private HLODControllerBase m_controller;
|
|
private int m_id;
|
|
private int m_level;
|
|
private float m_distnace;
|
|
|
|
protected Action<Handle> m_loadDoneCallback;
|
|
|
|
}
|
|
|
|
private class HandleLoader : Handle
|
|
{
|
|
public HandleLoader(HLODControllerBase controller, int id, int level, float distance,
|
|
bool isHighObject,
|
|
Action<Handle> loadDoneCallback)
|
|
: base(controller, id, level, distance, isHighObject, loadDoneCallback)
|
|
{
|
|
}
|
|
|
|
public void StartLoad()
|
|
{
|
|
m_isLoading = true;
|
|
if (m_isHighObject)
|
|
{
|
|
Controller.LoadHighObject(Id, (go) =>
|
|
{
|
|
m_isLoading = false;
|
|
m_loadedObject = go;
|
|
FinishLoad();
|
|
m_loadDoneCallback?.Invoke(this);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
Controller.LoadLowObject(Id, (go) =>
|
|
{
|
|
m_isLoading = false;
|
|
m_loadedObject = go;
|
|
FinishLoad();
|
|
m_loadDoneCallback?.Invoke(this);
|
|
});
|
|
}
|
|
}
|
|
|
|
public void Unload()
|
|
{
|
|
if (m_isHighObject)
|
|
{
|
|
Controller.UnloadHighObject(Id);
|
|
}
|
|
else
|
|
{
|
|
Controller.UnloadLowObject(Id);
|
|
}
|
|
}
|
|
|
|
private void FinishLoad()
|
|
{
|
|
LoadManager.Instance.FinishLoad(this);
|
|
}
|
|
}
|
|
|
|
private LinkedList<HandleLoader> m_loadQueue = new LinkedList<HandleLoader>();
|
|
|
|
public Handle LoadHighObject(HLODControllerBase controller, int id, int level, float distance, Action<Handle> loadDoneCallback)
|
|
{
|
|
HandleLoader handle = new HandleLoader(controller, id, level, distance, true, loadDoneCallback);
|
|
InsertHandle(handle);
|
|
return handle;
|
|
}
|
|
public Handle LoadLowObject(HLODControllerBase controller, int id, int level, float distance, Action<Handle> loadDoneCallback)
|
|
{
|
|
HandleLoader handle = new HandleLoader(controller, id, level, distance, false, loadDoneCallback);
|
|
InsertHandle(handle);
|
|
return handle;
|
|
}
|
|
|
|
public void UnloadHighObject(Handle handle)
|
|
{
|
|
HandleLoader handleLoader = handle as HandleLoader;
|
|
if (handleLoader == null)
|
|
{
|
|
Debug.LogError("Handle is not created by LoadManager.");
|
|
return;
|
|
}
|
|
|
|
handleLoader.Unload();
|
|
}
|
|
public void UnloadLowObject(Handle handle)
|
|
{
|
|
HandleLoader handleLoader = handle as HandleLoader;
|
|
if (handleLoader == null)
|
|
{
|
|
Debug.LogError("Handle is not created by LoadManager.");
|
|
return;
|
|
}
|
|
|
|
handleLoader.Unload();
|
|
}
|
|
|
|
public void RegisterController(HLODControllerBase controller)
|
|
{
|
|
}
|
|
|
|
public void UnregisterController(HLODControllerBase controller)
|
|
{
|
|
var node = m_loadQueue.First;
|
|
while (node != null)
|
|
{
|
|
if (node.Value.Controller == controller)
|
|
{
|
|
var remove = node;
|
|
node = node.Next;
|
|
m_loadQueue.Remove(remove);
|
|
}
|
|
else
|
|
{
|
|
node = node.Next;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void InsertHandle(HandleLoader handle)
|
|
{
|
|
var node = m_loadQueue.First;
|
|
while (node != null && node.Value.Level < handle.Level)
|
|
{
|
|
node = node.Next;
|
|
}
|
|
|
|
while (node != null && node.Value.Level == handle.Level && node.Value.Distance < handle.Distance)
|
|
{
|
|
node = node.Next;
|
|
}
|
|
|
|
if (node == null)
|
|
{
|
|
m_loadQueue.AddLast(handle);
|
|
}
|
|
else
|
|
{
|
|
m_loadQueue.AddBefore(node, handle);
|
|
}
|
|
|
|
if ( m_loadQueue.Count == 1)
|
|
StartLoadFirst();
|
|
}
|
|
|
|
private void StartLoadFirst()
|
|
{
|
|
var node = m_loadQueue.First;
|
|
if (node == null || node.Value.IsLoading == true)
|
|
return;
|
|
|
|
node.Value.StartLoad();
|
|
}
|
|
private void FinishLoad(HandleLoader handle)
|
|
{
|
|
m_loadQueue.Remove(handle);
|
|
StartLoadFirst();
|
|
}
|
|
|
|
}
|
|
} |