VR4RoboticArm2/VR4RoboticArm/Library/PackageCache/com.meta.xr.sdk.interaction/Runtime/Scripts/Utils/AssertUtils.cs
IonutMocanu 48cccc22ad Main2
2025-09-08 11:13:29 +03:00

274 lines
16 KiB
C#

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.Assertions;
namespace Oculus.Interaction
{
public static class AssertUtils
{
public const string HiglightColor = "#3366ff";
/// <summary>
/// Asserts that the expression is True.
/// In case of failure, it will print an error showing where the failure happened.
/// </summary>
/// <param name="component">The component to which the value expression belongs</param>
/// <param name="value">The expression that should be true</param>
/// <param name="whyItFailed">Optional parameter specifying the reason the assert failed</param>
/// <param name="whereItFailed">Optional parameter specifying where the failure can be found.
/// If none is provided it will print the component address (GameObject->Component).</param>
/// <param name="howToFix">Optional parameter suggesting how to fix the problem.</param>
[Conditional("UNITY_ASSERTIONS")]
public static void AssertIsTrue(this Component component,
bool value,
string whyItFailed = null, string whereItFailed = null, string howToFix = null)
{
string gameObjectName = component.name;
string componentName = component.GetType().Name;
Assert.IsTrue(value,
(whereItFailed ?? $"At GameObject <color={HiglightColor}><b>{gameObjectName}</b></color>, component <b>{componentName}</b>. ") +
(whyItFailed ?? "") +
(howToFix ?? ""));
}
/// <summary>
/// Asserts that an Aspect exists.
/// In case of failure, it will print an error showing why it failed, where it failed
/// and suggest how to fix it.
/// </summary>
/// <typeparam name="TValue">The type of Aspect to be checked</typeparam>
/// <param name="component">The component requiring this Aspect</param>
/// <param name="aspect">The Aspect to be checked</param>
/// <param name="aspectLocation">The expected location of the Aspect</param>
/// <param name="whyItFailed">Optional parameter specifying the reason the assert failed.
/// If none is provided it will print the expected aspect type and location.</param>
/// <param name="whereFailed">Optional parameter specifying where the failure can be found.
/// If none is provided it will print the component address (GameObject->Component).</param>
/// <param name="howToFix">Optional parameter suggesting how to fix the problem.
/// If none is provided it will suggest assigning an Aspect of the required type to the expected location.</param>
[Conditional("UNITY_ASSERTIONS")]
public static void AssertAspect<TValue>(this Component component,
TValue aspect, string aspectLocation,
string whyItFailed = null, string whereFailed = null, string howToFix = null)
where TValue : class
{
string gameObjectName = component.name;
string componentName = component.GetType().Name;
string niceVariableName = Nicify(aspectLocation);
string aspectType = typeof(TValue).Name;
Assert.IsNotNull(aspect,
(whereFailed ?? $"At GameObject <color={HiglightColor}><b>{gameObjectName}</b></color>, component <b>{componentName}</b>. ") +
(whyItFailed ?? $"Could not find the required Aspect <b>{aspectType}</b> in the associated <b>{niceVariableName}</b>. ") +
(howToFix ?? $"Assign an Aspect of type <b>{aspectType}</b> to the associated <b>{niceVariableName}</b>."));
}
/// <summary>
/// Asserts that a Serialized Field in a Component is not null.
/// In case of failure, it will print an error showing why it failed, where it failed
/// and suggest how to fix it.
/// </summary>
/// <typeparam name="TValue">The type of field to be checked</typeparam>
/// <param name="component">The component to which this field belongs.</param>
/// <param name="value">The value of the field.</param>
/// <param name="variableName">The printed name of the serialized field.</param>
/// <param name="whyItFailed">Optional parameter specifying the reason the assert failed.
/// If none is provided it will indicate that the field value was null.</param>
/// <param name="whereItFailed">Optional parameter specifying where the failure can be found.
/// If none is provided it will print the component address (GameObject->Component->Field Name).</param>
/// <param name="howToFix">Optional parameter suggesting how to fix the problem.
/// If none is provided it will suggest assigning a value of the required type to the field.</param>
[Conditional("UNITY_ASSERTIONS")]
public static void AssertField<TValue>(this Component component,
TValue value, string variableName,
string whyItFailed = null, string whereItFailed = null, string howToFix = null)
where TValue : class
{
string gameObjectName = component.name;
string componentName = component.GetType().Name;
string niceVariableName = Nicify(variableName);
string variableType = typeof(TValue).Name;
Assert.IsNotNull(value,
(whereItFailed ?? $"At GameObject <color={HiglightColor}><b>{gameObjectName}</b></color>, component <b>{componentName}</b>. ") +
(whyItFailed ?? $"Required <b>{niceVariableName}</b> reference is missing. ") +
(howToFix ?? $"Assign a <b>{variableType}</b> to the field <b>{niceVariableName}</b>."));
}
/// <summary>
/// Asserts that a Serialized collection in a Component is not null, is not empty and
/// all of its items exist.
/// In case of failure, it will print an error showing why it failed, where it failed
/// and suggest how to fix it.
/// </summary>
/// <typeparam name="TValue">The type of the items in the collection.</typeparam>
/// <param name="component">The component to which this collection belongs.</param>
/// <param name="value">The value of the collection.</param>
/// <param name="variableName">The printed name of the serialized collection.</param>
/// <param name="whyItFailed">Optional parameter specifying the reason the assert failed.
/// If none is provided it will indicate that the collection value needs at least one valid item.</param>
/// <param name="whereFailed">Optional parameter specifying where the failure can be found.
/// If none is provided it will print the component address (GameObject->Component->Collection Name).</param>
/// <param name="howToFix">Optional parameter suggesting how to fix the problem.
/// If none is provided it will suggest assigning at least one valid item of the required type to the collection.</param>
[Conditional("UNITY_ASSERTIONS")]
public static void AssertCollectionField<TValue>(this Component component,
IEnumerable<TValue> value, string variableName,
string whyItFailed = null, string whereFailed = null, string howToFix = null)
{
string gameObjectName = component.name;
string componentName = component.GetType().Name;
string niceVariableName = Nicify(variableName);
string variableType = typeof(TValue).Name;
Assert.IsTrue(value != null && value.Count() > 0,
(whereFailed ?? $"At GameObject <color={HiglightColor}><b>{gameObjectName}</b></color>: the <b>{componentName}</b> component has an missing or empty <b>{niceVariableName}</b> collection. ") +
(whyItFailed ?? "") +
(howToFix ?? $"Assign at least one <b>{variableType}</b> to the collection <b>{niceVariableName}</b>. "));
component.AssertCollectionItems(value, variableName);
}
/// <summary>
/// Asserts that each item in a Serialized collection in a Component is not null.
/// Note that the collection it might contain 0 items.
/// In case of failure, it will print an error showing why it failed, where it failed
/// and suggest how to fix it.
/// </summary>
/// <typeparam name="TValue">The type of the items in the collection</typeparam>
/// <param name="component">The component to which the collection belongs.</param>
/// <param name="value">The value of the collection.</param>
/// <param name="variableName">The printed name of the serialized collection.</param>
/// <param name="whyItFailed">Optional parameter specifying the reason the assert failed.
/// If none is provided it will indicate, for each failed item, that the item must not be null.</param>
/// <param name="whereItFailed">Optional parameter specifying where the failure can be found.
/// If none is provided it will print the component address (GameObject->Component->Collection Name).</param>
/// <param name="howToFix">Optional parameter suggesting how to fix the problem.
/// If none is provided it will suggest assigning a valid item of the required type to the collection at each missing index.</param>
[Conditional("UNITY_ASSERTIONS")]
public static void AssertCollectionItems<TValue>(this Component component,
IEnumerable<TValue> value, string variableName,
string whyItFailed = null, string whereItFailed = null, string howToFix = null)
{
string gameObjectName = component.name;
string componentName = component.GetType().Name;
string niceVariableName = Nicify(variableName);
string variableType = typeof(TValue).Name;
int index = 0;
foreach (TValue item in value)
{
Assert.IsFalse(item is null,
(whereItFailed ?? $"At GameObject <color={HiglightColor}><b>{gameObjectName}</b></color>, component <b>{componentName}</b>. ") +
(whyItFailed ?? $"Invalid item in the collection <b>{niceVariableName}</b> at index <b>{index}</b>. ") +
(howToFix ?? $"Assign a <b>{variableType}</b> to the collection <b>{niceVariableName}</b> at index <b>{index}</b>. "));
index++;
}
}
/// <summary>
/// Shows a Warning for each item in a Serialized collection in a Component that is null.
/// It works just for UnityEngine.Object collections,
/// Note that the collection it might contain 0 items.
/// In case of failure, it will print a warning showing why it failed, where it failed
/// and suggest how to fix it.
/// </summary>
/// <param name="component">The component to which the collection belongs.</param>
/// <param name="value">The value of the collection.</param>
/// <param name="variableName">The printed name of the serialized collection.</param>
/// <param name="whyItFailed">Optional parameter specifying the reason the assert failed.
/// If none is provided it will indicate, for each failed item, that the item must not be null.</param>
/// <param name="whereItFailed">Optional parameter specifying where the failure can be found.
/// If none is provided it will print the component address (GameObject->Component->Collection Name).</param>
/// <param name="howToFix">Optional parameter suggesting how to fix the problem.
/// If none is provided it will suggest assigning a valid item of the required type to the collection at each missing index.</param>
[Conditional("UNITY_ASSERTIONS")]
public static void WarnInspectorCollectionItems(this Component component,
IEnumerable<UnityEngine.Object> value, string variableName,
string whyItFailed = null, string whereItFailed = null, string howToFix = null)
{
string gameObjectName = component.name;
string componentName = component.GetType().Name;
string niceVariableName = Nicify(variableName);
string variableType = typeof(UnityEngine.Object).Name;
int index = 0;
foreach (UnityEngine.Object item in value)
{
string message = (whereItFailed ?? $"At GameObject <color={HiglightColor}><b>{gameObjectName}</b></color>, component <b>{componentName}</b>. ") +
(whyItFailed ?? $"Invalid item in the collection <b>{niceVariableName}</b> at index <b>{index}</b>. ") +
(howToFix ?? $"Assign a <b>{variableType}</b> to the collection <b>{niceVariableName}</b> at index <b>{index}</b> or remove the entry. ");
if (item == null)
{
UnityEngine.Debug.LogWarning(message, component);
}
index++;
}
}
/// <summary>
/// Displays a generic warning using the same identifiable messages as the Asserts
/// </summary>
/// <param name="component">Component throwing the warning</param>
/// <param name="variableName">Variable that failed</param>
/// <param name="whyItFailed">The failure reason, empty by default.</param>
/// <param name="whereItFailed">The location of the failure. Points to the component by default</param>
/// <param name="howToFix">How to fix the issue, empty by default.</param>
[Conditional("UNITY_ASSERTIONS")]
public static void LogWarning(this Component component,
string whyItFailed = null, string whereItFailed = null, string howToFix = null)
{
string gameObjectName = component.name;
string componentName = component.GetType().Name;
UnityEngine.Debug.LogWarning(
(whereItFailed ?? $"At GameObject <color={HiglightColor}><b>{gameObjectName}</b></color>, component <b>{componentName}</b>. ") +
(whyItFailed ?? string.Empty) +
(howToFix ?? string.Empty)
, component);
}
/// <summary>
/// Make a displayable name for a variable.
/// This function will insert spaces before capital letters and remove optional m_, _ or k followed by uppercase letter in front of the name.
/// </summary>
/// <param name="variableName">The variable name as used in code</param>
/// <returns>The nicified variable</returns>
public static string Nicify(string variableName)
{
variableName = Regex.Replace(variableName, "_([a-z])", match => match.Value.ToUpper(), RegexOptions.Compiled);
variableName = Regex.Replace(variableName, "m_|_", " ", RegexOptions.Compiled);
variableName = Regex.Replace(variableName, "k([A-Z])", "$1", RegexOptions.Compiled);
variableName = Regex.Replace(variableName, "([A-Z])", " $1", RegexOptions.Compiled);
variableName = variableName.Trim();
return variableName;
}
}
}