using UnityEditor;
using UnityEngine;
using System.IO;
using hedCommon.extension.editor;
using System.Collections.Generic;
using hedCommon.extension.runtime;
using extUnityComponents.transform;
using extUnityComponents;
using System;
using System.Reflection;
using hedCommon.time;
namespace hedCommon.symlinks
{
///
/// An editor utility for easily creating symlinks in your project.
///
/// Adds a Menu item under `Assets/Create/Folder(Symlink)`, and
/// draws a small indicator in the Project view for folders that are
/// symlinks.
///
[InitializeOnLoad]
public static class SymLinksOnHierarchyItemGUI
{
private const string SYMLINK_TOOLTIP = "In Symlink: ";
private const int MAX_SETUP_IN_ONE_FRAME = 10;
private const float TIME_BETWEEN_2_CHUNK_SETUP = 0.1f;
//Don't use dictionnary ! it crash !!
private static List _gameObjectsId = new List(300);
private static List _gameObjectsList = new List(300);
private static List _gameObjectsHasBeenSetup = new List(300);
private static List _gameObjectsIsInFrameWork = new List(300);
private static List _toolTipInfo = new List(300);
private static bool _needToSetup = false;
private static int _settupedGameObject = 0;
private static EditorChronoWithNoTimeEditor _timerBetween2ChunkSetup = new EditorChronoWithNoTimeEditor();
///
/// Static constructor subscribes to projectWindowItemOnGUI delegate.
///
static SymLinksOnHierarchyItemGUI()
{
EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyItemGUI;
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyItemGUI;
EditorApplication.hierarchyChanged -= OnHierarchyWindowChanged;
EditorApplication.hierarchyChanged += OnHierarchyWindowChanged;
_needToSetup = false;
_settupedGameObject = 0;
}
public static void ResetSymLinksDatas()
{
_gameObjectsId.Clear();
_gameObjectsList.Clear();
_toolTipInfo.Clear();
_gameObjectsHasBeenSetup.Clear();
_gameObjectsIsInFrameWork.Clear();
_settupedGameObject = 0;
}
[UnityEditor.Callbacks.DidReloadScripts]
private static void OnScriptsReloaded()
{
_needToSetup = true;
}
private static void OnHierarchyWindowChanged()
{
_needToSetup = true;
}
///
/// called at every frameGUI for every gaemObjects inside hierarchy
///
///
///
private static void OnHierarchyItemGUI(int instanceId, Rect selectionRect)
{
try
{
if (_needToSetup)
{
ResetHasBeenSetupOfGameObjects();
_needToSetup = false;
}
bool succes = _gameObjectsId.ContainIndex(instanceId, out int index);
if (!succes)
{
UnityEngine.Object targetGameObject = EditorUtility.InstanceIDToObject(instanceId);
if (targetGameObject == null)
{
return;
}
_gameObjectsId.Add(instanceId);
_gameObjectsList.Add(targetGameObject);
_toolTipInfo.Add(SYMLINK_TOOLTIP);
_gameObjectsHasBeenSetup.Add(false);
_gameObjectsIsInFrameWork.Add(false);
index = _gameObjectsId.Count - 1;
SetupGameObject(index);
}
if (!_gameObjectsHasBeenSetup[index])
{
SetupGameObject(index);
}
if (_gameObjectsIsInFrameWork[index])
{
DisplayMarker(selectionRect, _toolTipInfo[index]);
}
}
catch (Exception e) { Debug.Log(e); }
}
private static void ResetHasBeenSetupOfGameObjects()
{
_settupedGameObject = 0;
for (int i = 0; i < _gameObjectsHasBeenSetup.Count; i++)
{
_gameObjectsHasBeenSetup[i] = false;
_toolTipInfo[i] = SYMLINK_TOOLTIP;
}
}
///
/// From an instance id, setup the info:
/// HasBennSetup at true
/// determine if gameObject is inside framework or not !
///
///
///
private static void SetupGameObject(int index)
{
if (_settupedGameObject > MAX_SETUP_IN_ONE_FRAME)
{
_timerBetween2ChunkSetup.StartChrono(TIME_BETWEEN_2_CHUNK_SETUP);
_settupedGameObject = 0;
return;
}
if (_timerBetween2ChunkSetup.IsRunning())
{
return;
}
string toolTip = _toolTipInfo[index];
bool prefab = DetermineIfGameObjectIsInSymLink.IsPrefabsAndInSymLink(_gameObjectsList[index] as GameObject, ref SymLinksOnProjectWindowItemGUI.AllSymLinksAssetPathSaved, ref toolTip);
bool component = DetermineIfGameObjectIsInSymLink.HasComponentInSymLink(_gameObjectsList[index] as GameObject, ref SymLinksOnProjectWindowItemGUI.AllSymLinksAssetPathSaved, ref toolTip);
bool assets = DetermineIfGameObjectIsInSymLink.HasSymLinkAssetInsideComponent(_gameObjectsList[index] as GameObject, ref SymLinksOnProjectWindowItemGUI.AllSymLinksAssetPathSaved, ref toolTip);
bool isSomethingInsideFrameWork = prefab || component || assets;
_toolTipInfo[index] = toolTip;
_gameObjectsHasBeenSetup[index] = true;
_gameObjectsIsInFrameWork[index] = isSomethingInsideFrameWork;
_settupedGameObject++;
}
///
/// display the marker at the given position
///
///
private static void DisplayMarker(Rect selectionRect, string toolTip)
{
Rect r = new Rect(selectionRect);
r.x = r.width - 20;
r.width = 18;
ExtSymLinks.DisplayTinyMarker(selectionRect, toolTip);
}
}
}