/// <summary> Dock EditorWindow as tab on the parent host view of the existing EditorWindow. </summary> /// <param name="window"> The window whose host view to dock on. </param> /// <param name="tab"> The EditorWindow to dock. </param> public static void AddTab([NotNull] this EditorWindow window, EditorWindow tab) { var dockArea = window.ParentHostView(); if (dockArea == null) { #if DEV_MODE Debug.LogWarning("m_Parent of target window " + window.GetType().Name + " (\"" + window.name + "\") was null; can't add " + tab.GetType().Name + " (\"" + tab.name + "\") as tab. You might want to revert Layout to factory settings."); #endif return; } var dockAreaType = TypeExtensions.GetInternalEditorType("UnityEditor.DockArea"); var parentHostViewType = dockArea.GetType(); if (parentHostViewType != dockAreaType && !parentHostViewType.IsSubclassOf(dockAreaType)) { #if DEV_MODE Debug.LogWarning("m_Parent of target window " + window.GetType().Name + " (\"" + window.name + "\") was not a DockArea (but " + parentHostViewType.Name + "); can't add " + tab.GetType().Name + " (\"" + tab.name + "\") as tab."); #endif return; } #if UNITY_2018_3_OR_NEWER var types = ArrayTypePool <Type> .Create(2); types[1] = TypeExtensions.Bool; #else var types = ArrayPool <Type> .Create(1); #endif types[0] = typeof(EditorWindow); var addTabMethod = dockAreaType.GetMethod("AddTab", BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Any, types, null); ArrayTypePool <Type> .Dispose(ref types); #if UNITY_2018_3_OR_NEWER var parameters = ArrayTypePool <object> .Create(2); parameters[1] = true; #else var parameters = ArrayPool <object> .Create(1); #endif parameters[0] = tab; addTabMethod.Invoke(dockArea, parameters); }
/// <summary> /// Tries to cast arrays elements of type <typeparamref name="T"/> to array result, containing elements of type <typeparamref name="TTo"/>. /// If casting fails for any member, will return false and set result to null. /// </summary> /// <typeparam name="TTo"> /// Cast to an array with members of this type. </typeparam> /// <param name="sourceArray"> /// Array whose contents will be cast to target type.</param> /// <param name="disposeSourceArray"> /// True if we are allowed to pool the source array after the casting has been completed. Note that this does not guarantee that the array will get disposed.</param> /// <param name="result"> /// An array of type TTo[]. If target and source types are the same, simply equals sourceArray. Length of array will be equal or less than that of sourceArray, depending /// on whether or not all members can be cast. /// </param> /// <returns> /// True if casting succeeds for all array elements, otherwise returns false. /// </returns> public static bool TryCast <TTo>(T[] sourceArray, bool disposeSourceArray, out TTo[] result) where TTo : T { var fromType = sourceArray.GetType(); var toType = typeof(TTo[]); if (disposeSourceArray) { if (fromType.Equals(toType)) { #if DEV_MODE Debug.LogWarning("No need to cast from " + fromType.Name + " to " + toType.Name + " because they are the same"); #endif result = sourceArray as TTo[]; return(true); } } int count = sourceArray.Length; result = ArrayTypePool <TTo> .CreateInternal(count, false); try { for (int n = count - 1; n >= 0; n--) { result[n] = (TTo)sourceArray[n]; } } catch (InvalidCastException) { result = null; return(false); } if (disposeSourceArray) { Dispose(ref sourceArray); } return(true); }
/// <summary> /// Casts array with elements of type <typeparamref name="T"/> to array of elements of type <typeparamref name="TTo"/> /// </summary> /// <typeparam name="TTo"> /// Cast to an array with members of this type </typeparam> /// <param name="sourceArray"> /// Array whose contents will be cast to target type. </param> /// <param name="disposeSourceArray"> /// True if we are allowed to pool the source array after the casting has been completed. Note that this does not guarantee that the array will get disposed.</param> /// <returns> /// An array of type TTo[]. If target and source types are the same, simply returns sourceArray. /// </returns> public static TToStruct[] CastToValueTypeArray <TToStruct>(T[] sourceArray, bool disposeSourceArray = false) where TToStruct : struct { var fromType = sourceArray.GetType(); var toType = typeof(TToStruct[]); if (disposeSourceArray) { if (fromType == toType) { #if DEV_MODE Debug.LogWarning("No need to cast from " + fromType.Name + " to " + toType.Name + " because they are the same"); #endif return(sourceArray as TToStruct[]); } } int count = sourceArray.Length; var result = ArrayTypePool <TToStruct> .CreateInternal(count, false); for (int n = count - 1; n >= 0; n--) { result[n] = (TToStruct)(object)sourceArray[n]; } if (disposeSourceArray) { Dispose(ref sourceArray); #if DEV_MODE && PI_ASSERTATIONS var inspectors = InspectorUtility.ActiveManager.ActiveInstances; for (int n = inspectors.Count - 1; n >= 0; n--) { Debug.Assert(!inspectors[n].State.inspected.ContainsNullObjects()); } #endif } return(result); }
/// <summary> /// Casts array with elements of type <typeparamref name="T"/> to array of elements of type <typeparamref name="TTo"/>. /// Will skip elements that cannot be cast to target type. /// </summary> /// <typeparam name="TTo"> /// Cast to an array with members of this type. </typeparam> /// <param name="sourceArray"> /// Array whose contents will be cast to target type. </param> /// <param name="disposeSourceArray"> /// True if we are allowed to pool the source array after the casting has been completed. Note that this does not guarantee that the array will get disposed.</param> /// <returns> /// An array of type TTo[]. If target and source types are the same, simply returns sourceArray. Length of array will be equal or less than that of sourceArray, depending /// on whether or not all members can be cast. /// </returns> public static TTo[] CastWhereCastable <TTo>(T[] sourceArray, bool disposeSourceArray) where TTo : class, T { var fromType = sourceArray.GetType(); var toType = typeof(TTo[]); if (disposeSourceArray) { if (fromType.Equals(toType)) { #if DEV_MODE Debug.LogWarning("No need to cast from " + fromType.Name + " to " + toType.Name + " because they are the same"); #endif return(sourceArray as TTo[]); } } int count = sourceArray.Length; var result = ArrayTypePool <TTo> .CreateInternal(count, false); for (int n = count - 1; n >= 0; n--) { try { result[n] = (TTo)sourceArray[n]; } catch (InvalidCastException) { result = result.RemoveAt(n); } } if (disposeSourceArray) { Dispose(ref sourceArray); } return(result); }