mirror of
https://github.com/Facepunch/sbox-public.git
synced 2025-12-23 22:48:07 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
147 lines
4.5 KiB
C#
147 lines
4.5 KiB
C#
extern alias After;
|
|
extern alias Before;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using Mono.Cecil;
|
|
using Sandbox;
|
|
using Sandbox.ActionGraphs;
|
|
using Sandbox.Internal;
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using NodeLibrary = Facepunch.ActionGraphs.NodeLibrary;
|
|
|
|
namespace Hotload
|
|
{
|
|
[AttributeUsage( AttributeTargets.Field )]
|
|
public sealed class ResetAttribute : Attribute { }
|
|
|
|
public abstract class HotloadTests
|
|
{
|
|
private static void ResetStaticFields<TAttrib>()
|
|
where TAttrib : Attribute
|
|
{
|
|
foreach ( var type in typeof( TAttrib ).Assembly.GetTypes() )
|
|
{
|
|
foreach ( var fieldInfo in type.GetFields( BindingFlags.Static | BindingFlags.Public ) )
|
|
{
|
|
if ( fieldInfo.GetCustomAttribute<TAttrib>() != null )
|
|
{
|
|
fieldInfo.SetValue( null, fieldInfo.FieldType.IsValueType ? Activator.CreateInstance( fieldInfo.FieldType ) : null );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected static Sandbox.Hotload CreateHotload()
|
|
{
|
|
Sandbox.Hotload.AssemblyNameFormatter = name => name.Name;
|
|
|
|
var hotload = new Sandbox.Hotload { TraceRoots = true, TracePaths = true, IncludeTypeTimings = true, IncludeProcessorTimings = true };
|
|
|
|
hotload.WatchAssembly( "Sandbox.Hotload.Test" );
|
|
hotload.WatchAssembly( "Sandbox.Engine", t => t.Name == nameof( ReflectionQueryCache ) );
|
|
hotload.ReplacingAssembly( typeof( Before.TestClass1 ).Assembly, typeof( After.TestClass1 ).Assembly );
|
|
hotload.AssemblyResolver = new DefaultAssemblyResolver();
|
|
|
|
hotload.AddUpgrader<Sandbox.Upgraders.AutoSkipUpgrader>();
|
|
hotload.AddUpgraders( typeof( TypeDescription ).Assembly );
|
|
|
|
return hotload;
|
|
}
|
|
|
|
protected static HotloadResult Hotload( bool allowErrors = false )
|
|
{
|
|
var hotload = CreateHotload();
|
|
var result = hotload.UpdateReferences();
|
|
|
|
Assert.IsFalse( result.NoAction );
|
|
|
|
Console.WriteLine( $"NoAction = {result.NoAction}" );
|
|
Console.WriteLine( $"InstancesProcessed = {result.InstancesProcessed}" );
|
|
Console.WriteLine( $"ProcessingTime = {result.ProcessingTime:F2}ms" );
|
|
Console.WriteLine( $"result.Entries = {result.Entries.Count}" );
|
|
|
|
foreach ( var entry in result.Entries )
|
|
{
|
|
Console.WriteLine( $" [{entry.Type}] {entry.ToString().Replace( "\n", "\n " )}" );
|
|
}
|
|
|
|
Console.WriteLine( "Type Timings:" );
|
|
foreach ( var pair in result.TypeTimings.OrderByDescending( x => x.Value.Milliseconds ) )
|
|
{
|
|
Console.WriteLine( $" {pair.Key}:" );
|
|
Console.WriteLine( $" Instances = {pair.Value.Instances}" );
|
|
Console.WriteLine( $" TimeSpan = {pair.Value.Milliseconds:F2}ms" );
|
|
Console.WriteLine( " Roots:" );
|
|
|
|
foreach ( var rootPair in pair.Value.Roots.OrderByDescending( x => x.Value.Milliseconds ) )
|
|
{
|
|
Console.WriteLine( $" {rootPair.Key}:" );
|
|
Console.WriteLine( $" Instances = {rootPair.Value.Instances}" );
|
|
Console.WriteLine( $" TimeSpan = {rootPair.Value.Milliseconds:F2}ms" );
|
|
}
|
|
}
|
|
|
|
Console.WriteLine( "Processor Timings:" );
|
|
foreach ( var pair in result.ProcessorTimings.OrderByDescending( x => x.Value.Milliseconds ) )
|
|
{
|
|
Console.WriteLine( $" {pair.Key}:" );
|
|
Console.WriteLine( $" Instances = {pair.Value.Instances}" );
|
|
Console.WriteLine( $" TimeSpan = {pair.Value.Milliseconds:F2}ms" );
|
|
Console.WriteLine( " Roots:" );
|
|
|
|
foreach ( var rootPair in pair.Value.Roots.OrderByDescending( x => x.Value.Milliseconds ) )
|
|
{
|
|
Console.WriteLine( $" {rootPair.Key}:" );
|
|
Console.WriteLine( $" Instances = {rootPair.Value.Instances}" );
|
|
Console.WriteLine( $" TimeSpan = {rootPair.Value.Milliseconds:F2}ms" );
|
|
}
|
|
}
|
|
|
|
if ( !allowErrors )
|
|
{
|
|
Assert.IsFalse( result.HasErrors );
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private NodeLibrary _oldNodeLibrary;
|
|
|
|
public TypeLibrary TypeLibrary;
|
|
public NodeLibrary Nodes => Game.NodeLibrary;
|
|
|
|
[TestInitialize]
|
|
public void Initialize()
|
|
{
|
|
_oldNodeLibrary = Nodes;
|
|
|
|
ResetStaticFields<Before.ResetAttribute>();
|
|
ResetStaticFields<After.ResetAttribute>();
|
|
ResetStaticFields<ResetAttribute>();
|
|
|
|
TypeLibrary = new TypeLibrary();
|
|
TypeLibrary.AddAssembly( typeof( LogNodes ).Assembly, false );
|
|
|
|
Game.NodeLibrary = new NodeLibrary( new TypeLoader( () => TypeLibrary ), new GraphLoader() );
|
|
|
|
var result = Nodes.AddAssembly( typeof( LogNodes ).Assembly );
|
|
|
|
foreach ( var (method, e) in result.Errors )
|
|
{
|
|
Debug.WriteLine( $"{method}: {e}" );
|
|
}
|
|
|
|
Assert.IsFalse( result.AlreadyAdded );
|
|
Assert.AreEqual( 0, result.Errors.Count );
|
|
}
|
|
|
|
[TestCleanup]
|
|
public void Cleanup()
|
|
{
|
|
Game.NodeLibrary = _oldNodeLibrary;
|
|
}
|
|
}
|
|
}
|