Files
sbox-public/engine/Sandbox.Engine/Editor/Hammer/ValidateAttribute.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

98 lines
3.2 KiB
C#

using Sandbox;
using Sandbox.Internal;
/// <summary>
/// Validates a property using a method.
/// </summary>
[AttributeUsage( AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true )]
public class ValidateAttribute : Attribute
{
protected string _methodName;
protected Type _methodOwnerType;
protected LogLevel _status;
protected string _message;
/// <summary>
/// Specifies a method in the same class to use for validation.
/// </summary>
/// <param name="condition">Name of the validation method in the current class</param>
/// <param name="message">Message to display when validation fails</param>
/// <param name="status">severity level to use when validation fails</param>
/// <code>
/// [Validate(nameof(IsLineMaterial), "Material should derive from 'line.shader'.", LogLevel.Warn)]
/// public Material Material { get; set; }
///
/// private bool IsLineMaterial(Material material)
/// {
/// return material != null &amp;&amp; material.Shader.Name.Contains("line.shader");
/// }
/// </code>
public ValidateAttribute( string condition, string message, LogLevel status )
{
_methodName = condition;
_status = status;
_message = message;
}
/// <summary>
/// Specifies a static method in another class to use for validation.
/// </summary>
/// <param name="type">The type containing the static validation method</param>
/// <param name="condition">Name of the static validation method</param>
/// <param name="message">Message to display when validation fails</param>
/// <param name="status">severity level to use when validation fails</param>
/// <code>
/// [Validate(typeof(MaterialValidators), nameof(MaterialValidators.IsLineMaterial), "Material should derive from 'line.shader'.", LogLevel.Warn)]
/// public Material Material { get; set; }
///
/// // In MaterialValidators.cs
/// public static class MaterialValidators
/// {
/// public static bool IsLineMaterial(Material material)
/// {
/// return material != null &amp;&amp; material.Shader.Name.Contains("line.shader");
/// }
/// }
/// </code>
public ValidateAttribute( Type type, string condition, string message, LogLevel status )
{
_methodName = condition;
_methodOwnerType = type;
_status = status;
_message = message;
}
public record struct Result( LogLevel Status, string Message = "", bool Success = false );
/// <summary>
/// Validates a property value using the specified method.
/// </summary>
public Result Validate( object targetObject, TypeDescription td, object propertyValue )
{
if ( _methodOwnerType != null )
{
td = GlobalGameNamespace.TypeLibrary.GetType( _methodOwnerType );
}
var methodDesc = td.GetMethod( _methodName );
if ( methodDesc == null )
{
return new Result( LogLevel.Error, $"Validation method '{_methodName}' not found on {td.Name}" );
}
try
{
bool validationPassed = methodDesc.InvokeWithReturn<bool>( _methodOwnerType != null ? null : targetObject, [propertyValue] );
if ( validationPassed )
return new Result( LogLevel.Info, Success: true );
else
return new Result( _status, _message );
}
catch ( Exception ex )
{
return new Result( LogLevel.Error, $"Error executing validation method '{_methodName}': {ex.Message}" );
}
}
}