You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
289 lines
7.9 KiB
289 lines
7.9 KiB
namespace Mapbox.Editor
|
|
{
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Mapbox.Unity.Map;
|
|
using Mapbox.Unity.MeshGeneration.Data;
|
|
|
|
/// <summary>
|
|
/// EditorHelper class provides methods for working with serialzed properties.
|
|
/// Methods in this class are based on the spacepuppy-unity-framework, available at the url below.
|
|
/// https://github.com/lordofduct/spacepuppy-unity-framework/tree/d8d592e212b26cad53264421d22c3d26c6799923/SpacepuppyBaseEditor.
|
|
/// </summary>
|
|
public static class EditorHelper
|
|
{
|
|
|
|
[UnityEditor.Callbacks.DidReloadScripts]
|
|
private static void OnScriptsReloaded()
|
|
{
|
|
if (Application.isEditor)
|
|
{
|
|
AbstractMap abstractMap = UnityEngine.Object.FindFirstObjectByType<AbstractMap>();
|
|
|
|
if (abstractMap == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
UnityTile[] unityTiles = abstractMap.GetComponentsInChildren<UnityTile>();
|
|
|
|
for (int i = 0; i < unityTiles.Length; i++)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(unityTiles[i].gameObject);
|
|
}
|
|
|
|
abstractMap.DestroyChildObjects();
|
|
if (EditorApplication.isPlaying)
|
|
{
|
|
abstractMap.ResetMap();
|
|
return;
|
|
}
|
|
if (abstractMap.IsEditorPreviewEnabled == true)
|
|
{
|
|
if (EditorApplication.isPlayingOrWillChangePlaymode)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
abstractMap.DisableEditorPreview();
|
|
abstractMap.EnableEditorPreview();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static void CheckForModifiedProperty<T>(SerializedProperty property, T targetObject, bool forceHasChanged = false)
|
|
{
|
|
MapboxDataProperty targetObjectAsDataProperty = GetMapboxDataPropertyObject(targetObject);
|
|
if (targetObjectAsDataProperty != null)
|
|
{
|
|
targetObjectAsDataProperty.HasChanged = forceHasChanged || property.serializedObject.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
|
|
public static void CheckForModifiedProperty(SerializedProperty property, bool forceHasChanged = false)
|
|
{
|
|
CheckForModifiedProperty(property, GetTargetObjectOfProperty(property), forceHasChanged);
|
|
}
|
|
|
|
public static MapboxDataProperty GetMapboxDataPropertyObject<T>(T targetObject)
|
|
{
|
|
return targetObject as MapboxDataProperty;
|
|
}
|
|
|
|
public static bool DidModifyProperty<T>(SerializedProperty property, T targetObject)
|
|
{
|
|
MapboxDataProperty targetObjectAsDataProperty = targetObject as MapboxDataProperty;
|
|
return (property.serializedObject.ApplyModifiedProperties() && targetObjectAsDataProperty != null);
|
|
}
|
|
|
|
public static bool DidModifyProperty(SerializedProperty property)
|
|
{
|
|
return DidModifyProperty(property, GetTargetObjectOfProperty(property));
|
|
}
|
|
|
|
public static IEnumerable<SerializedProperty> GetChildren(this SerializedProperty property)
|
|
{
|
|
property = property.Copy();
|
|
var nextElement = property.Copy();
|
|
bool hasNextElement = nextElement.NextVisible(false);
|
|
if (!hasNextElement)
|
|
{
|
|
nextElement = null;
|
|
}
|
|
|
|
property.NextVisible(true);
|
|
while (true)
|
|
{
|
|
if ((SerializedProperty.EqualContents(property, nextElement)))
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
yield return property;
|
|
|
|
bool hasNext = property.NextVisible(false);
|
|
if (!hasNext)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static System.Type GetTargetType(this SerializedObject obj)
|
|
{
|
|
if (obj == null) return null;
|
|
|
|
if (obj.isEditingMultipleObjects)
|
|
{
|
|
var c = obj.targetObjects[0];
|
|
return c.GetType();
|
|
}
|
|
else
|
|
{
|
|
return obj.targetObject.GetType();
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Gets the object the property represents.
|
|
/// </summary>
|
|
/// <param name="prop"></param>
|
|
/// <returns></returns>
|
|
public static object GetTargetObjectOfProperty(SerializedProperty prop)
|
|
{
|
|
var path = prop.propertyPath.Replace(".Array.data[", "[");
|
|
object obj = prop.serializedObject.targetObject;
|
|
var elements = path.Split('.');
|
|
foreach (var element in elements)
|
|
{
|
|
if (element.Contains("["))
|
|
{
|
|
var elementName = element.Substring(0, element.IndexOf("[", StringComparison.CurrentCulture));
|
|
var index = System.Convert.ToInt32(element.Substring(element.IndexOf("[", StringComparison.CurrentCulture)).Replace("[", "").Replace("]", ""));
|
|
obj = GetValue_Imp(obj, elementName, index);
|
|
}
|
|
else
|
|
{
|
|
obj = GetValue_Imp(obj, element);
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
public static void SetTargetObjectOfProperty(SerializedProperty prop, object value)
|
|
{
|
|
var path = prop.propertyPath.Replace(".Array.data[", "[");
|
|
object obj = prop.serializedObject.targetObject;
|
|
var elements = path.Split('.');
|
|
foreach (var element in elements.Take(elements.Length - 1))
|
|
{
|
|
if (element.Contains("["))
|
|
{
|
|
var elementName = element.Substring(0, element.IndexOf("[", StringComparison.CurrentCulture));
|
|
var index = System.Convert.ToInt32(element.Substring(element.IndexOf("[", StringComparison.CurrentCulture)).Replace("[", "").Replace("]", ""));
|
|
obj = GetValue_Imp(obj, elementName, index);
|
|
}
|
|
else
|
|
{
|
|
obj = GetValue_Imp(obj, element);
|
|
}
|
|
}
|
|
|
|
if (System.Object.ReferenceEquals(obj, null)) return;
|
|
|
|
try
|
|
{
|
|
var element = elements.Last();
|
|
|
|
if (element.Contains("["))
|
|
{
|
|
var tp = obj.GetType();
|
|
var elementName = element.Substring(0, element.IndexOf("[", StringComparison.CurrentCulture));
|
|
var index = System.Convert.ToInt32(element.Substring(element.IndexOf("[", StringComparison.CurrentCulture)).Replace("[", "").Replace("]", ""));
|
|
var field = tp.GetField(elementName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
|
var arr = field.GetValue(obj) as System.Collections.IList;
|
|
arr[index] = value;
|
|
}
|
|
else
|
|
{
|
|
var tp = obj.GetType();
|
|
var field = tp.GetField(element, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
|
if (field != null)
|
|
{
|
|
field.SetValue(obj, value);
|
|
}
|
|
}
|
|
|
|
}
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Gets the object that the property is a member of
|
|
/// </summary>
|
|
/// <param name="prop"></param>
|
|
/// <returns></returns>
|
|
public static object GetTargetObjectWithProperty(SerializedProperty prop)
|
|
{
|
|
var path = prop.propertyPath.Replace(".Array.data[", "[");
|
|
object obj = prop.serializedObject.targetObject;
|
|
var elements = path.Split('.');
|
|
foreach (var element in elements.Take(elements.Length - 1))
|
|
{
|
|
if (element.Contains("["))
|
|
{
|
|
var elementName = element.Substring(0, element.IndexOf("[", StringComparison.CurrentCulture));
|
|
var index = System.Convert.ToInt32(element.Substring(element.IndexOf("[", StringComparison.CurrentCulture)).Replace("[", "").Replace("]", ""));
|
|
obj = GetValue_Imp(obj, elementName, index);
|
|
}
|
|
else
|
|
{
|
|
obj = GetValue_Imp(obj, element);
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
private static object GetValue_Imp(object source, string name)
|
|
{
|
|
if (source == null)
|
|
return null;
|
|
var type = source.GetType();
|
|
|
|
while (type != null)
|
|
{
|
|
var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
|
if (f != null)
|
|
return f.GetValue(source);
|
|
|
|
var p = type.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
|
|
if (p != null)
|
|
return p.GetValue(source, null);
|
|
|
|
type = type.BaseType;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static object GetValue_Imp(object source, string name, int index)
|
|
{
|
|
var enumerable = GetValue_Imp(source, name) as System.Collections.IEnumerable;
|
|
if (enumerable == null) return null;
|
|
var enm = enumerable.GetEnumerator();
|
|
|
|
for (int i = 0; i <= index; i++)
|
|
{
|
|
if (!enm.MoveNext()) return null;
|
|
}
|
|
return enm.Current;
|
|
}
|
|
|
|
public static int GetChildPropertyCount(SerializedProperty property, bool includeGrandChildren = false)
|
|
{
|
|
var pstart = property.Copy();
|
|
var pend = property.GetEndProperty();
|
|
int cnt = 0;
|
|
|
|
pstart.Next(true);
|
|
while (!SerializedProperty.EqualContents(pstart, pend))
|
|
{
|
|
cnt++;
|
|
pstart.Next(includeGrandChildren);
|
|
}
|
|
|
|
return cnt;
|
|
}
|
|
}
|
|
}
|
|
|