mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-04-19 13:59:22 -04:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
157 lines
3.5 KiB
C#
157 lines
3.5 KiB
C#
using Sandbox.Resources;
|
|
|
|
namespace Editor;
|
|
|
|
/// <summary>
|
|
/// A control widget that shows a ResourceGenerator. This will either be a dropdown which
|
|
/// will pop up the config editor for the generator, or will be an inline editor with the
|
|
/// key properties, with an edit button on the side.
|
|
/// </summary>
|
|
public class ResourceGeneratorControlWidget : ControlWidget
|
|
{
|
|
GenericControlWidget Editor { get; set; }
|
|
protected ResourceGenerator Generator { get; set; }
|
|
|
|
bool _isDirty = false;
|
|
bool _isGenerating = false;
|
|
|
|
public ResourceGeneratorControlWidget( ResourceGenerator generator, SerializedProperty property ) : base( property )
|
|
{
|
|
Layout = Layout.Row();
|
|
Layout.Spacing = 2;
|
|
|
|
MouseTracking = true;
|
|
AcceptDrops = true;
|
|
IsDraggable = true;
|
|
|
|
var generatorObject = generator.GetSerialized();
|
|
Generator = generator;
|
|
|
|
LoadFromResource( property.GetValue<Resource>() );
|
|
|
|
var prop = EditorTypeLibrary.CreateProperty<ResourceGenerator>( "Generator", generatorObject );
|
|
|
|
Editor = new GenericControlWidget( prop );
|
|
generatorObject.OnPropertyChanged = x => MakeDirty();
|
|
|
|
BuildContent();
|
|
|
|
_ = UpdateGenerator();
|
|
}
|
|
|
|
protected virtual void BuildContent()
|
|
{
|
|
var col = Layout.AddColumn();
|
|
col.Add( Editor );
|
|
col.AddStretchCell();
|
|
Layout.AddStretchCell();
|
|
}
|
|
|
|
/// <summary>
|
|
/// We might want existing data from an embedded resource - in that case, deserialize it
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
void LoadFromResource( Resource resource )
|
|
{
|
|
var embeddedResource = resource?.EmbeddedResource;
|
|
|
|
if ( embeddedResource is null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Not a matching compiler
|
|
if ( embeddedResource.Value.ResourceGenerator != EditorTypeLibrary.GetType( Generator.GetType() ).ClassName )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Generator.Deserialize( embeddedResource.Value.Data );
|
|
}
|
|
|
|
void MakeDirty()
|
|
{
|
|
_isDirty = true;
|
|
}
|
|
|
|
async Task UpdateGenerator()
|
|
{
|
|
_isGenerating = true;
|
|
|
|
try
|
|
{
|
|
var resource = await Generator.FindOrCreateObjectAsync( ResourceGenerator.Options.Default, default );
|
|
SerializedProperty.SetValue( resource );
|
|
OnResourceChanged( resource );
|
|
Update();
|
|
}
|
|
finally
|
|
{
|
|
_isGenerating = false;
|
|
}
|
|
}
|
|
|
|
protected virtual void OnResourceChanged( Resource resource )
|
|
{
|
|
|
|
}
|
|
|
|
[EditorEvent.Frame]
|
|
public void FrameUpdate()
|
|
{
|
|
if ( _isGenerating ) return;
|
|
if ( !_isDirty ) return;
|
|
|
|
if ( Generator is not null )
|
|
{
|
|
_isDirty = false;
|
|
_ = UpdateGenerator();
|
|
}
|
|
}
|
|
|
|
protected override void PaintUnder()
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a ResourceGeneratorControlWidget for a specific generator
|
|
/// </summary>
|
|
internal static Widget Create( ResourceGenerator generator, SerializedProperty serializedProperty )
|
|
{
|
|
var allTypes = EditorTypeLibrary.GetTypes<ResourceGeneratorControlWidget>();
|
|
var editor = allTypes.OrderByDescending( x => Score( generator, x ) ).FirstOrDefault();
|
|
|
|
return editor.Create<Widget>( [generator, serializedProperty] );
|
|
}
|
|
|
|
/// <summary>
|
|
/// score a ResourceGeneratorControlWidget based on how well it matches the target ResourceGenerator
|
|
/// </summary>
|
|
private static int Score( ResourceGenerator target, TypeDescription targetEditor )
|
|
{
|
|
var editorTarget = targetEditor.GetAttribute<CanEditAttribute>()?.Type;
|
|
|
|
//
|
|
// Target editor doesn't have a CanEdit
|
|
//
|
|
if ( editorTarget == null ) return 100;
|
|
|
|
int score = 1000;
|
|
var targetType = target.GetType();
|
|
|
|
while ( targetType != null )
|
|
{
|
|
if ( editorTarget.IsAssignableFrom( targetType ) )
|
|
{
|
|
return score;
|
|
}
|
|
|
|
score -= 100;
|
|
targetType = targetType.BaseType;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|