mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-02 11:28:19 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
111 lines
2.4 KiB
C#
111 lines
2.4 KiB
C#
using Facepunch.ActionGraphs;
|
|
|
|
namespace Sandbox;
|
|
|
|
[AttributeUsage( AttributeTargets.Class, AllowMultiple = true, Inherited = false )]
|
|
public class CustomEmbeddedEditorAttribute : Attribute
|
|
{
|
|
public Type TargetType { get; }
|
|
public CustomEmbeddedEditorAttribute( Type targetType = null )
|
|
{
|
|
TargetType = targetType;
|
|
}
|
|
}
|
|
|
|
[AttributeUsage( AttributeTargets.Class, AllowMultiple = true, Inherited = false )]
|
|
public class CustomEditorAttribute : Attribute
|
|
{
|
|
public Type TargetType { get; }
|
|
public Type[] WithAllAttributes { get; set; }
|
|
public bool ForMethod { get; set; }
|
|
public string NamedEditor { get; set; }
|
|
public bool ForInterface { get; set; }
|
|
|
|
public CustomEditorAttribute( Type targetType = null )
|
|
{
|
|
TargetType = targetType;
|
|
}
|
|
|
|
public float GetEditorScore( SerializedProperty property )
|
|
{
|
|
// This is a method, and it doesn't apply to it
|
|
if ( property.IsMethod != ForMethod )
|
|
return 0;
|
|
|
|
float score = 0;
|
|
|
|
if ( ForMethod )
|
|
score += 100;
|
|
|
|
if ( property.PropertyType.IsInterface && ForInterface )
|
|
score += 100;
|
|
|
|
var t = property.PropertyType;
|
|
if ( t is null ) return score;
|
|
|
|
if ( Either.IsEitherType( t ) )
|
|
{
|
|
t = typeof( Either );
|
|
}
|
|
|
|
if ( Nullable.GetUnderlyingType( t ) is { } elemType )
|
|
{
|
|
t = elemType;
|
|
}
|
|
|
|
//
|
|
// This attribute has a type set, look at that
|
|
//
|
|
if ( TargetType is not null && !ForMethod )
|
|
{
|
|
//
|
|
// Order by derived classes so we get the most relevent editor
|
|
//
|
|
Type baseType = TargetType;
|
|
while ( baseType.BaseType != null )
|
|
{
|
|
score += 10.0f;
|
|
baseType = baseType.BaseType;
|
|
}
|
|
|
|
if ( TargetType == t ) score += 1000.0f; // directly targets this class
|
|
else if ( t.IsGenericType && TargetType == t.GetGenericTypeDefinition() ) score += 500.0f; // generic type target
|
|
else if ( t.IsAssignableTo( TargetType ) ) score += 100.0f; // directly targets a base type
|
|
else return -100; // definitely not this!
|
|
}
|
|
|
|
//
|
|
// Properties can have [Editor( "NamedEditor" )]
|
|
//
|
|
if ( NamedEditor is not null )
|
|
{
|
|
if ( property.TryGetAttribute<EditorAttribute>( out var editorAttribute ) && string.Equals( editorAttribute.Value, NamedEditor ) )
|
|
{
|
|
score += 1000;
|
|
}
|
|
else
|
|
{
|
|
score -= 1000;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Needs all of these attributes
|
|
//
|
|
if ( WithAllAttributes is not null )
|
|
{
|
|
foreach ( var a in WithAllAttributes )
|
|
{
|
|
if ( !property.HasAttribute( a ) )
|
|
return -100;
|
|
|
|
score += 1000;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return score;
|
|
}
|
|
}
|