Compare commits

...

59 Commits

Author SHA1 Message Date
Silver
d49075a970 Update and clean up Prototype manager methods 2022-02-11 00:27:34 -07:00
Silver
a67acd453c Split out Interface and Attribute 2022-02-11 00:26:58 -07:00
ElectroJr
b540f04a7a Version: 0.8.52 2022-02-10 21:46:08 +13:00
Leon Friedrich
bcaa7001ad Hopefully fix container occlusion bug? (#2464) 2022-02-10 09:29:26 +01:00
metalgearsloth
3f0fba7b4e Version: 0.8.51 2022-02-10 12:57:00 +11:00
metalgearsloth
d7d7a53045 Raise appearance event by ref 2022-02-10 12:56:14 +11:00
metalgearsloth
40daba9adf Version: 0.8.50 2022-02-10 12:53:26 +11:00
mirrorcult
5665f8eb1c Abstract VisualizerSystem (#2522) 2022-02-10 12:52:42 +11:00
metalgearsloth
8f0d562f3e Version: 0.8.49 2022-02-10 11:21:29 +11:00
ike709
f3950e940e Re-adds UpdateEntityTree() to EntityLookup's interface (#2525) 2022-02-10 11:15:09 +11:00
Leon Friedrich
3fdca65cc9 Make occluder use try get map (#2516) 2022-02-10 01:40:11 +11:00
ike709
23d0b8a555 Expose LastTick on IGameTiming (#2518) 2022-02-08 14:02:36 +11:00
mirrorcult
452b03d5a6 Merge pull request #2513 from metalgearsloth/2022-02-07_EnsureCompOut 2022-02-07 13:41:59 -07:00
metalgearsloth
c8f2dab381 Don't crash on VV edit for angles (#2517) 2022-02-08 02:58:55 +11:00
metalgearsloth
7409df07f8 Merge remote-tracking branch 'upstream/master' into 2022-02-07_EnsureCompOut 2022-02-07 19:55:45 +11:00
metalgearsloth
973406b91d Cleanup contact code a lot (#2480) 2022-02-07 13:10:58 +11:00
metalgearsloth
2e646fe2b6 EntityQueryEnumerator "fix" (#2501) 2022-02-07 12:06:50 +11:00
mirrorcult
6b902d22d4 Merge pull request #2504 from metalgearsloth/2022-02-03_appearance-events
Appearance data event
2022-02-06 11:23:01 -07:00
metalgearsloth
83e6d52e58 Version: 0.8.47 2022-02-07 02:56:24 +11:00
metalgearsloth
025fdcd0b3 GetHardAABB (#2514) 2022-02-07 02:10:02 +11:00
metalgearsloth
fe3ace92bd Another helper 2022-02-07 02:04:57 +11:00
metalgearsloth
317070f167 Some animation helpers for cargo telepad too 2022-02-07 02:00:31 +11:00
metalgearsloth
3524363ad4 fix build 2022-02-07 01:44:27 +11:00
metalgearsloth
90287dbb09 Merge remote-tracking branch 'upstream/master' into 2022-02-03_appearance-events
# Conflicts:
#	Robust.Shared/GameObjects/Components/Appearance/AppearanceComponent.cs
2022-02-07 01:42:53 +11:00
metalgearsloth
9a2f35f2d3 Also pass comp 2022-02-07 01:42:32 +11:00
metalgearsloth
3f10dbe770 EnsureComponent<T> with out variable
Useful for EnsureComponent<T>(uid, out var comp) && comp.Thing
2022-02-07 00:07:01 +11:00
metalgearsloth
8fcba93ada Don't draw 0-mass non-hard fixtures as invalid (#2499) 2022-02-06 19:42:47 +11:00
ElectroJr
35366b5bc1 Version: 0.8.46 2022-02-06 15:18:56 +13:00
mirrorcult
d8bf31ecc4 Merge pull request #2510 from ElectroJr/fix-sprite-bug 2022-02-05 15:23:25 -07:00
Pieter-Jan Briers
de4d255841 Analyzer to enforce classes to be either [Virtual], abstract, or sealed. (#2469)
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2022-02-05 19:31:58 +01:00
Leon Friedrich
ec768c563f Add spin command (#2484) 2022-02-05 12:38:02 +11:00
metalgearsloth
2114d2bc67 Funny struct enumerator for xform kids (#2487) 2022-02-05 12:32:13 +11:00
ElectroJr
43478d0e45 avoid unnecessary RoundToCardinal calls 2022-02-05 14:27:31 +13:00
Leon Friedrich
561699b26e Replace EntityDirtyEvent with C# event. (#2495) 2022-02-05 12:23:51 +11:00
ElectroJr
460923e54d fix sprite bug 2022-02-05 14:10:28 +13:00
Kara D
c299104f0c Version: 0.8.45 2022-02-04 14:35:35 -07:00
Kara D
224bebeeb5 ok then 2022-02-04 14:35:15 -07:00
Kara D
52c8e8ecdf Version: 0.8.44 2022-02-04 14:20:48 -07:00
mirrorcult
ac636b2703 Merge pull request #2441 from metalgearsloth/2022-01-20_more-caching 2022-02-04 14:13:26 -07:00
mirrorcult
a892f9ac99 Merge pull request #2506 from metalgearsloth/2022-02-04_xform-children 2022-02-04 14:13:18 -07:00
mirrorcult
2ebee8f40c Merge pull request #2508 from metalgearsloth/2022-02-04_powa 2022-02-04 14:13:10 -07:00
mirrorcult
43741dc5fc Merge pull request #2490 from metalgearsloth/2022-02-01_game-state 2022-02-04 14:12:56 -07:00
metalgearsloth
da9467b678 Reduce FindGridsIntersecting allocs 2022-02-04 17:44:44 +11:00
Leon Friedrich
8f24a7b4fc Reduce ContainerHelper IoCManager resolves (#2498) 2022-02-04 12:51:29 +11:00
metalgearsloth
ff48959e97 Merge remote-tracking branch 'upstream/master' into 2022-01-20_more-caching 2022-02-04 12:46:01 +11:00
metalgearsloth
1d1db2e109 Also that sneaky pvs one 2022-02-04 12:40:40 +11:00
metalgearsloth
6a902286cd Merge remote-tracking branch 'upstream/master' into 2022-01-20_more-caching 2022-02-04 12:38:32 +11:00
metalgearsloth
53034e6f05 Replace xform children sortedset with hashset 2022-02-04 12:27:51 +11:00
metalgearsloth
6a31c5649c Tweak 2022-02-03 18:03:56 +11:00
metalgearsloth
7bd90578dc Appearance data event
We agreed that AppearanceVisualizers should probably be deprecated in favour of just using a system instead.
2022-02-03 18:01:31 +11:00
metalgearsloth
773a068b7d Merge remote-tracking branch 'upstream/master' into 2022-02-01_game-state 2022-02-02 22:13:17 +11:00
metalgearsloth
b98cd3e6e1 Reduce batch for lowerpop I guess 2022-02-01 23:11:35 +11:00
metalgearsloth
987c8e8229 Reduce gamestate allocs
Parallel.ForEach has no right to be that expensive.
2022-02-01 23:11:05 +11:00
metalgearsloth
1f6170c000 Merge remote-tracking branch 'upstream/master' into 2022-01-20_more-caching 2022-01-31 18:21:23 +11:00
metalgearsloth
e438e53d36 Silly caching 2022-01-31 17:50:30 +11:00
metalgearsloth
792608f0d0 Merge remote-tracking branch 'upstream/master' into 2022-01-20_more-caching 2022-01-31 17:42:09 +11:00
metalgearsloth
7b5678fd0f woops 2022-01-31 17:34:49 +11:00
metalgearsloth
88c328a636 Smol entityquery change 2022-01-31 17:33:21 +11:00
metalgearsloth
f9573530a8 Nuke entitylookup to get it merged 2022-01-31 17:30:53 +11:00
640 changed files with 2530 additions and 2231 deletions

View File

@@ -1,4 +1,4 @@
<Project>
<!-- This file automatically reset by Tools/version.py -->
<PropertyGroup><Version>0.8.43</Version></PropertyGroup>
<PropertyGroup><Version>0.8.52</Version></PropertyGroup>
</Project>

View File

@@ -1,10 +1,14 @@
using Microsoft.CodeAnalysis;
namespace Robust.Generators
namespace Robust.Analyzers;
public static class Diagnostics
{
public static class Diagnostics
{
public static SuppressionDescriptor MeansImplicitAssignment =>
new SuppressionDescriptor("RADC1000", "CS0649", "Marked as implicitly assigned.");
}
public const string IdExplicitInterface = "RA0000";
public const string IdSerializable = "RA0001";
public const string IdFriend = "RA0002";
public const string IdExplicitVirtual = "RA0003";
public static SuppressionDescriptor MeansImplicitAssignment =>
new SuppressionDescriptor("RADC1000", "CS0649", "Marked as implicitly assigned.");
}

View File

@@ -24,14 +24,14 @@ namespace Robust.Analyzers
SyntaxKind.OverrideKeyword
};
public const string DiagnosticId = "RA0000";
private const string Title = "No explicit interface specified";
private const string MessageFormat = "No explicit interface specified";
private const string Description = "Make sure to specify the interface in your method-declaration.";
private const string Category = "Usage";
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new(
Diagnostics.IdExplicitInterface,
"No explicit interface specified",
"No explicit interface specified",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
description: "Make sure to specify the interface in your method-declaration.");
private const string RequiresExplicitImplementationAttributeMetadataName =
"Robust.Shared.Analyzers.RequiresExplicitImplementationAttribute";

View File

@@ -0,0 +1,176 @@
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Robust.Analyzers;
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class ExplicitVirtualAnalyzer : DiagnosticAnalyzer
{
internal const string Attribute = "Robust.Shared.Analyzers.VirtualAttribute";
[SuppressMessage("ReSharper", "RS2008")]
private static readonly DiagnosticDescriptor Rule = new(
Diagnostics.IdExplicitVirtual,
"Class must be explicitly marked as [Virtual], abstract, static or sealed",
"Class must be explicitly marked as [Virtual], abstract, static or sealed",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
description: "Class must be explicitly marked as [Virtual], abstract, static or sealed.");
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ClassDeclaration);
}
private static bool HasAttribute(INamedTypeSymbol namedTypeSymbol, INamedTypeSymbol attrSymbol)
{
return namedTypeSymbol.GetAttributes()
.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attrSymbol));
}
private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
var attrSymbol = context.Compilation.GetTypeByMetadataName(Attribute);
var classDecl = (ClassDeclarationSyntax)context.Node;
var classSymbol = context.SemanticModel.GetDeclaredSymbol(classDecl);
if (classSymbol == null)
return;
if (classSymbol.IsSealed || classSymbol.IsAbstract || classSymbol.IsStatic)
return;
if (HasAttribute(classSymbol, attrSymbol))
return;
var diag = Diagnostic.Create(Rule, classDecl.Keyword.GetLocation());
context.ReportDiagnostic(diag);
}
}
// Doesn't work as I'd hoped: Roslyn doesn't provide an API for global usings and I can't get batch changes to work.
/*
[ExportCodeFixProvider(LanguageNames.CSharp)]
public sealed class ExplicitVirtualCodeFixProvider : CodeFixProvider
{
private const string TitleSealed = "Annotate class as sealed.";
private const string TitleVirtual = "Annotate class as [Virtual].";
private const string TitleAbstract = "Annotate class as abstract.";
private const string TitleStatic = "Annotate class as static.";
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
foreach (var diagnostic in context.Diagnostics)
{
var span = diagnostic.Location.SourceSpan;
var classDecl = root.FindToken(span.Start).Parent.AncestorsAndSelf().OfType<ClassDeclarationSyntax>()
.First();
context.RegisterCodeFix(
CodeAction.Create(
TitleVirtual,
c => FixVirtualAsync(context.Document, classDecl, c),
TitleVirtual),
diagnostic);
context.RegisterCodeFix(
CodeAction.Create(
TitleStatic,
c => FixStaticAsync(context.Document, classDecl, c),
TitleStatic),
diagnostic);
context.RegisterCodeFix(
CodeAction.Create(
TitleSealed,
c => FixSealedAsync(context.Document, classDecl, c),
TitleSealed),
diagnostic);
context.RegisterCodeFix(
CodeAction.Create(
TitleAbstract,
c => FixAbstractAsync(context.Document, classDecl, c),
TitleAbstract),
diagnostic);
}
}
private async Task<Document> FixVirtualAsync(
Document document,
ClassDeclarationSyntax classDecl,
CancellationToken cancellationToken)
{
var ns = "Robust.Shared.Analyzers";
var attrib = SyntaxFactory.Attribute(SyntaxFactory.ParseName("Virtual"));
var newClassDecl = classDecl.AddAttributeLists(
SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(new[] { attrib })));
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken);
root = root.ReplaceNode(classDecl, newClassDecl);
var options = await document.GetOptionsAsync(cancellationToken);
if (root.Usings.All(u => u.Name.ToString() != ns))
{
root = root.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(ns)));
}
return document.WithSyntaxRoot(root);
}
private async Task<Document> FixStaticAsync(
Document document,
ClassDeclarationSyntax classDecl,
CancellationToken cancellationToken)
{
var newClassDecl = classDecl.AddModifiers(SyntaxFactory.Token(SyntaxKind.StaticKeyword));
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken);
root = root.ReplaceNode(classDecl, newClassDecl);
return document.WithSyntaxRoot(root);
}
private async Task<Document> FixAbstractAsync(
Document document,
ClassDeclarationSyntax classDecl,
CancellationToken cancellationToken)
{
var newClassDecl = classDecl.AddModifiers(SyntaxFactory.Token(SyntaxKind.AbstractKeyword));
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken);
root = root.ReplaceNode(classDecl, newClassDecl);
return document.WithSyntaxRoot(root);
}
private async Task<Document> FixSealedAsync(
Document document,
ClassDeclarationSyntax classDecl,
CancellationToken cancellationToken)
{
var newClassDecl = classDecl.AddModifiers(SyntaxFactory.Token(SyntaxKind.SealedKeyword));
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken);
root = root.ReplaceNode(classDecl, newClassDecl);
return document.WithSyntaxRoot(root);
}
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(Diagnostics.IdExplicitVirtual);
}
*/

View File

@@ -14,15 +14,15 @@ namespace Robust.Analyzers
{
const string FriendAttribute = "Robust.Shared.Analyzers.FriendAttribute";
public const string DiagnosticId = "RA0002";
private const string Title = "Tried to access friend-only member";
private const string MessageFormat = "Tried to access member \"{0}\" in class \"{1}\" which can only be accessed by friend classes";
private const string Description = "Make sure to specify the accessing class in the friends attribute.";
private const string Category = "Usage";
[SuppressMessage("ReSharper", "RS2008")]
private static readonly DiagnosticDescriptor Rule = new (DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Error, true, Description);
private static readonly DiagnosticDescriptor Rule = new (
Diagnostics.IdFriend,
"Tried to access friend-only member",
"Tried to access member \"{0}\" in class \"{1}\" which can only be accessed by friend classes",
"Usage",
DiagnosticSeverity.Error,
true,
"Make sure to specify the accessing class in the friends attribute.");
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);

View File

@@ -1,9 +1,7 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Robust.Generators;
namespace Robust.Analyzers
{

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>9</LangVersion>
<LangVersion>10</LangVersion>
</PropertyGroup>
<ItemGroup>

View File

@@ -17,19 +17,21 @@ namespace Robust.Analyzers
public class SerializableAnalyzer : DiagnosticAnalyzer
{
// Metadata of the analyzer
public const string DiagnosticId = "RA0001";
// You could use LocalizedString but it's a little more complicated for this sample
private const string Title = "Class not marked as (Net)Serializable";
private const string MessageFormat = "Class not marked as (Net)Serializable";
private const string Description = "The class should be marked as (Net)Serializable.";
private const string Category = "Usage";
private const string RequiresSerializableAttributeMetadataName = "Robust.Shared.Analyzers.RequiresSerializableAttribute";
private const string SerializableAttributeMetadataName = "System.SerializableAttribute";
private const string NetSerializableAttributeMetadataName = "Robust.Shared.Serialization.NetSerializableAttribute";
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new(
Diagnostics.IdSerializable,
"Class not marked as (Net)Serializable",
"Class not marked as (Net)Serializable",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
description: "The class should be marked as (Net)Serializable.");
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
@@ -139,7 +141,8 @@ namespace Robust.Analyzers
return document.WithSyntaxRoot(root);
}
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(SerializableAnalyzer.DiagnosticId);
public sealed override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(Diagnostics.IdSerializable);
public override FixAllProvider GetFixAllProvider()
{

View File

@@ -1,7 +1,9 @@
using BenchmarkDotNet.Attributes;
using Robust.Shared.Analyzers;
namespace Robust.Benchmarks.NumericsHelpers
{
[Virtual]
public class AddBenchmark
{
[Params(32, 128)]

View File

@@ -4,7 +4,7 @@ using System;
namespace Robust.Benchmarks
{
internal class Program
internal static class Program
{
// --allCategories=ctg1,ctg2
// --anyCategories=ctg1,ctg2

View File

@@ -9,7 +9,7 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
namespace Robust.Benchmarks.Serialization
{
public class BenchmarkIntSerializer : ITypeSerializer<int, ValueDataNode>
public sealed class BenchmarkIntSerializer : ITypeSerializer<int, ValueDataNode>
{
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
IDependencyCollection dependencies, ISerializationContext? context = null)

View File

@@ -2,6 +2,7 @@
using System.Linq;
using BenchmarkDotNet.Attributes;
using Robust.Benchmarks.Serialization.Definitions;
using Robust.Shared.Analyzers;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown;
using Robust.Shared.Serialization.Markdown.Mapping;
@@ -13,6 +14,7 @@ using YamlDotNet.RepresentationModel;
namespace Robust.Benchmarks.Serialization.Copy
{
[MemoryDiagnoser]
[Virtual]
public class SerializationCopyBenchmark : SerializationBenchmark
{
public SerializationCopyBenchmark()

View File

@@ -3,7 +3,7 @@ using Robust.Shared.Serialization;
namespace Robust.Benchmarks.Serialization.Definitions
{
public class BenchmarkFlags
public sealed class BenchmarkFlags
{
public const int Zero = 1 << 0;
public const int ThirtyOne = 1 << 31;

View File

@@ -1,8 +1,10 @@
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Analyzers;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Robust.Benchmarks.Serialization.Definitions
{
[DataDefinition]
[Virtual]
public class DataDefinitionWithString
{
[DataField("string")]

View File

@@ -11,7 +11,7 @@ namespace Robust.Benchmarks.Serialization.Definitions
/// Taken from content.
/// </summary>
[Prototype("seed")]
public class SeedDataDefinition : IPrototype
public sealed class SeedDataDefinition : IPrototype
{
public const string Prototype = @"
- type: seed

View File

@@ -1,9 +1,11 @@
using BenchmarkDotNet.Attributes;
using Robust.Shared.Analyzers;
using Robust.Shared.Serialization.Manager;
namespace Robust.Benchmarks.Serialization.Initialize
{
[MemoryDiagnoser]
[Virtual]
public class SerializationInitializeBenchmark : SerializationBenchmark
{
[IterationCleanup]

View File

@@ -1,6 +1,7 @@
using System.IO;
using BenchmarkDotNet.Attributes;
using Robust.Benchmarks.Serialization.Definitions;
using Robust.Shared.Analyzers;
using Robust.Shared.Serialization.Manager.Result;
using Robust.Shared.Serialization.Markdown;
using Robust.Shared.Serialization.Markdown.Mapping;
@@ -12,6 +13,7 @@ using YamlDotNet.RepresentationModel;
namespace Robust.Benchmarks.Serialization.Read
{
[MemoryDiagnoser]
[Virtual]
public class SerializationReadBenchmark : SerializationBenchmark
{
public SerializationReadBenchmark()

View File

@@ -1,5 +1,6 @@
using BenchmarkDotNet.Attributes;
using Robust.Benchmarks.Serialization.Definitions;
using Robust.Shared.Analyzers;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.Markdown.Sequence;
using Robust.Shared.Serialization.Markdown.Value;
@@ -7,6 +8,7 @@ using Robust.Shared.Serialization.Markdown.Value;
namespace Robust.Benchmarks.Serialization
{
[MemoryDiagnoser]
[Virtual]
public class SerializationArrayBenchmark : SerializationBenchmark
{
public SerializationArrayBenchmark()

View File

@@ -2,6 +2,7 @@
using System.IO;
using BenchmarkDotNet.Attributes;
using Robust.Benchmarks.Serialization.Definitions;
using Robust.Shared.Analyzers;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown;
using Robust.Shared.Serialization.Markdown.Mapping;
@@ -13,6 +14,7 @@ using YamlDotNet.RepresentationModel;
namespace Robust.Benchmarks.Serialization.Write
{
[MemoryDiagnoser]
[Virtual]
public class SerializationWriteBenchmark : SerializationBenchmark
{
public SerializationWriteBenchmark()

View File

@@ -3,7 +3,7 @@ using Robust.Shared.Animations;
namespace Robust.Client.Animations
{
public class AnimationTrackControlProperty : AnimationTrackProperty
public sealed class AnimationTrackControlProperty : AnimationTrackProperty
{
public string? Property { get; set; }

View File

@@ -58,7 +58,7 @@ namespace Robust.Client.Audio.Midi
void Shutdown();
}
internal class MidiManager : IMidiManager
internal sealed class MidiManager : IMidiManager
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IResourceManagerInternal _resourceManager = default!;
@@ -392,7 +392,7 @@ namespace Robust.Client.Audio.Midi
/// <summary>
/// This class is used to load soundfonts.
/// </summary>
private class ResourceLoaderCallbacks : SoundFontLoaderCallbacks
private sealed class ResourceLoaderCallbacks : SoundFontLoaderCallbacks
{
private readonly Dictionary<int, Stream> _openStreams = new();
private int _nextStreamId = 1;

View File

@@ -180,7 +180,7 @@ namespace Robust.Client.Audio.Midi
internal void InternalDispose();
}
internal class MidiRenderer : IMidiRenderer
internal sealed class MidiRenderer : IMidiRenderer
{
[Dependency] private readonly IClydeAudio _clydeAudio = default!;
[Dependency] private readonly ITaskManager _taskManager = default!;

View File

@@ -20,7 +20,7 @@ using Robust.Shared.Utility;
namespace Robust.Client
{
/// <inheritdoc />
public class BaseClient : IBaseClient
public sealed class BaseClient : IBaseClient
{
[Dependency] private readonly IClientNetManager _net = default!;
[Dependency] private readonly IPlayerManager _playMan = default!;
@@ -291,7 +291,7 @@ namespace Robust.Client
/// <summary>
/// Event arguments for when something changed with the player.
/// </summary>
public class PlayerEventArgs : EventArgs
public sealed class PlayerEventArgs : EventArgs
{
/// <summary>
/// The session that triggered the event.
@@ -310,7 +310,7 @@ namespace Robust.Client
/// <summary>
/// Event arguments for when the RunLevel has changed in the BaseClient.
/// </summary>
public class RunLevelChangedEventArgs : EventArgs
public sealed class RunLevelChangedEventArgs : EventArgs
{
/// <summary>
/// RunLevel that the BaseClient switched from.
@@ -335,7 +335,7 @@ namespace Robust.Client
/// <summary>
/// Info about the server and player that is sent to the client while connecting.
/// </summary>
public class ServerInfo
public sealed class ServerInfo
{
public ServerInfo(string serverName)
{

View File

@@ -2,7 +2,7 @@
namespace Robust.Client.Console
{
public class ClientConGroupController : IClientConGroupController
public sealed class ClientConGroupController : IClientConGroupController
{
private IClientConGroupImplementation? _implementation;
public event Action? ConGroupUpdated;

View File

@@ -14,7 +14,7 @@ using Robust.Shared.Utility;
namespace Robust.Client.Console
{
public class AddStringArgs : EventArgs
public sealed class AddStringArgs : EventArgs
{
public string Text { get; }
@@ -30,7 +30,7 @@ namespace Robust.Client.Console
}
}
public class AddFormattedMessageArgs : EventArgs
public sealed class AddFormattedMessageArgs : EventArgs
{
public readonly FormattedMessage Message;
@@ -41,7 +41,7 @@ namespace Robust.Client.Console
}
/// <inheritdoc cref="IClientConsoleHost" />
internal class ClientConsoleHost : ConsoleHost, IClientConsoleHost
internal sealed class ClientConsoleHost : ConsoleHost, IClientConsoleHost
{
[Dependency] private readonly IClientConGroupController _conGroup = default!;
@@ -209,7 +209,7 @@ namespace Robust.Client.Console
/// These dummies are made purely so list and help can list server-side commands.
/// </summary>
[Reflect(false)]
internal class ServerDummyCommand : IConsoleCommand
internal sealed class ServerDummyCommand : IConsoleCommand
{
internal ServerDummyCommand(string command, string help, string description)
{

View File

@@ -59,7 +59,7 @@ namespace Robust.Client.Console.Commands
}
[UsedImplicitly]
public class SaveConfig : IConsoleCommand
public sealed class SaveConfig : IConsoleCommand
{
public string Command => "saveconfig";
public string Description => "Saves the client configuration to the config file";

View File

@@ -6,7 +6,7 @@ using Robust.Shared.Console;
namespace Robust.Client.Console.Commands
{
class ClearCommand : IConsoleCommand
sealed class ClearCommand : IConsoleCommand
{
public string Command => "cls";
public string Help => "Clears the debug console of all messages.";
@@ -18,7 +18,7 @@ namespace Robust.Client.Console.Commands
}
}
class FillCommand : IConsoleCommand
sealed class FillCommand : IConsoleCommand
{
public string Command => "fill";
public string Help => "Fills the console with some nonsense for debugging.";

View File

@@ -30,7 +30,7 @@ using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Robust.Client.Console.Commands
{
internal class DumpEntitiesCommand : IConsoleCommand
internal sealed class DumpEntitiesCommand : IConsoleCommand
{
public string Command => "dumpentities";
public string Help => "Dump entity list";
@@ -47,7 +47,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class GetComponentRegistrationCommand : IConsoleCommand
internal sealed class GetComponentRegistrationCommand : IConsoleCommand
{
public string Command => "getcomponentregistration";
public string Help => "Usage: getcomponentregistration <componentName>";
@@ -93,7 +93,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ToggleMonitorCommand : IConsoleCommand
internal sealed class ToggleMonitorCommand : IConsoleCommand
{
public string Command => "monitor";
@@ -148,7 +148,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ExceptionCommand : IConsoleCommand
internal sealed class ExceptionCommand : IConsoleCommand
{
public string Command => "fuck";
public string Help => "Throws an exception";
@@ -160,7 +160,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ShowPositionsCommand : IConsoleCommand
internal sealed class ShowPositionsCommand : IConsoleCommand
{
public string Command => "showpos";
public string Help => "";
@@ -173,7 +173,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ShowRayCommand : IConsoleCommand
internal sealed class ShowRayCommand : IConsoleCommand
{
public string Command => "showrays";
public string Help => "Usage: showrays <raylifetime>";
@@ -200,7 +200,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class DisconnectCommand : IConsoleCommand
internal sealed class DisconnectCommand : IConsoleCommand
{
public string Command => "disconnect";
public string Help => "";
@@ -212,7 +212,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class EntityInfoCommand : IConsoleCommand
internal sealed class EntityInfoCommand : IConsoleCommand
{
public string Command => "entfo";
@@ -264,7 +264,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class SnapGridGetCell : IConsoleCommand
internal sealed class SnapGridGetCell : IConsoleCommand
{
public string Command => "sggcell";
public string Help => "sggcell <gridID> <vector2i>\nThat vector2i param is in the form x<int>,y<int>.";
@@ -313,7 +313,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class SetPlayerName : IConsoleCommand
internal sealed class SetPlayerName : IConsoleCommand
{
public string Command => "overrideplayername";
public string Description => "Changes the name used when attempting to connect to the server.";
@@ -333,7 +333,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class LoadResource : IConsoleCommand
internal sealed class LoadResource : IConsoleCommand
{
public string Command => "ldrsc";
public string Description => "Pre-caches a resource.";
@@ -370,7 +370,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ReloadResource : IConsoleCommand
internal sealed class ReloadResource : IConsoleCommand
{
public string Command => "rldrsc";
public string Description => "Reloads a resource.";
@@ -404,7 +404,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class GridTileCount : IConsoleCommand
internal sealed class GridTileCount : IConsoleCommand
{
public string Command => "gridtc";
public string Description => "Gets the tile count of a grid";
@@ -438,7 +438,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class GuiDumpCommand : IConsoleCommand
internal sealed class GuiDumpCommand : IConsoleCommand
{
public string Command => "guidump";
public string Description => "Dump GUI tree to /guidump.txt in user data.";
@@ -512,7 +512,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class UITestCommand : IConsoleCommand
internal sealed class UITestCommand : IConsoleCommand
{
public string Command => "uitest";
public string Description => "Open a dummy UI testing window";
@@ -644,7 +644,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class SetClipboardCommand : IConsoleCommand
internal sealed class SetClipboardCommand : IConsoleCommand
{
public string Command => "setclipboard";
public string Description => "Sets the system clipboard";
@@ -657,7 +657,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class GetClipboardCommand : IConsoleCommand
internal sealed class GetClipboardCommand : IConsoleCommand
{
public string Command => "getclipboard";
public string Description => "Gets the system clipboard";
@@ -670,7 +670,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ToggleLight : IConsoleCommand
internal sealed class ToggleLight : IConsoleCommand
{
public string Command => "togglelight";
public string Description => "Toggles light rendering.";
@@ -684,7 +684,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ToggleFOV : IConsoleCommand
internal sealed class ToggleFOV : IConsoleCommand
{
public string Command => "togglefov";
public string Description => "Toggles fov for client.";
@@ -698,7 +698,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ToggleHardFOV : IConsoleCommand
internal sealed class ToggleHardFOV : IConsoleCommand
{
public string Command => "togglehardfov";
public string Description => "Toggles hard fov for client (for debugging space-station-14#2353).";
@@ -712,7 +712,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ToggleShadows : IConsoleCommand
internal sealed class ToggleShadows : IConsoleCommand
{
public string Command => "toggleshadows";
public string Description => "Toggles shadow rendering.";
@@ -725,7 +725,7 @@ namespace Robust.Client.Console.Commands
mgr.DrawShadows = !mgr.DrawShadows;
}
}
internal class ToggleLightBuf : IConsoleCommand
internal sealed class ToggleLightBuf : IConsoleCommand
{
public string Command => "togglelightbuf";
public string Description => "Toggles lighting rendering. This includes shadows but not FOV.";
@@ -739,7 +739,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class GcCommand : IConsoleCommand
internal sealed class GcCommand : IConsoleCommand
{
public string Command => "gc";
public string Description => "Run the GC.";
@@ -761,7 +761,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class GcFullCommand : IConsoleCommand
internal sealed class GcFullCommand : IConsoleCommand
{
public string Command => "gcf";
public string Description => "Run the GC, fully, compacting LOH and everything.";
@@ -774,7 +774,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class GcModeCommand : IConsoleCommand
internal sealed class GcModeCommand : IConsoleCommand
{
public string Command => "gc_mode";
@@ -816,7 +816,7 @@ namespace Robust.Client.Console.Commands
}
internal class SerializeStatsCommand : IConsoleCommand
internal sealed class SerializeStatsCommand : IConsoleCommand
{
public string Command => "szr_stats";
@@ -836,7 +836,7 @@ namespace Robust.Client.Console.Commands
}
internal class ChunkInfoCommand : IConsoleCommand
internal sealed class ChunkInfoCommand : IConsoleCommand
{
public string Command => "chunkinfo";
public string Description => "Gets info about a chunk under your mouse cursor.";
@@ -865,7 +865,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class ReloadShadersCommand : IConsoleCommand
internal sealed class ReloadShadersCommand : IConsoleCommand
{
public string Command => "rldshader";
@@ -1036,7 +1036,7 @@ namespace Robust.Client.Console.Commands
}
internal class ClydeDebugLayerCommand : IConsoleCommand
internal sealed class ClydeDebugLayerCommand : IConsoleCommand
{
public string Command => "cldbglyr";
public string Description => "Toggle fov and light debug layers";
@@ -1061,7 +1061,7 @@ namespace Robust.Client.Console.Commands
}
}
internal class GetKeyInfoCommand : IConsoleCommand
internal sealed class GetKeyInfoCommand : IConsoleCommand
{
public string Command => "keyinfo";
public string Description => "Keys key info for a key";

View File

@@ -4,7 +4,7 @@ using Robust.Shared.GameObjects;
namespace Robust.Client.Console.Commands
{
public class GridChunkBBCommand : IConsoleCommand
public sealed class GridChunkBBCommand : IConsoleCommand
{
public string Command => "showchunkbb";
public string Description => "Displays chunk bounds for the purposes of rendering";

View File

@@ -5,7 +5,7 @@ using Robust.Shared.Network;
namespace Robust.Client.Console.Commands
{
class HelpCommand : IConsoleCommand
sealed class HelpCommand : IConsoleCommand
{
public string Command => "help";
public string Help => "When no arguments are provided, displays a generic help text. When an argument is passed, display the help text for the command with that name.";
@@ -44,7 +44,7 @@ namespace Robust.Client.Console.Commands
}
}
class ListCommand : IConsoleCommand
sealed class ListCommand : IConsoleCommand
{
public string Command => "list";
public string Help => "Usage: list [filter]\n" +

View File

@@ -4,7 +4,7 @@ using Robust.Shared.Console;
namespace Robust.Client.Console.Commands
{
class LogSetLevelCommand : IConsoleCommand
sealed class LogSetLevelCommand : IConsoleCommand
{
public string Command => "loglevel";
public string Description => "Changes the log level for a provided sawmill.";
@@ -40,7 +40,7 @@ namespace Robust.Client.Console.Commands
}
}
class TestLog : IConsoleCommand
sealed class TestLog : IConsoleCommand
{
public string Command => "testlog";
public string Description => "Writes a test log to a sawmill.";

View File

@@ -4,7 +4,7 @@ using Robust.Shared.IoC;
namespace Robust.Client.Console.Commands
{
class HardQuitCommand : IConsoleCommand
sealed class HardQuitCommand : IConsoleCommand
{
public string Command => "hardquit";
public string Description => "Kills the game client instantly.";
@@ -16,7 +16,7 @@ namespace Robust.Client.Console.Commands
}
}
class QuitCommand : IConsoleCommand
sealed class QuitCommand : IConsoleCommand
{
public string Command => "quit";
public string Description => "Shuts down the game client gracefully.";

View File

@@ -6,7 +6,7 @@ using Robust.Shared.IoC;
namespace Robust.Client.Console.Commands
{
[UsedImplicitly]
public class SetInputContextCommand : IConsoleCommand
public sealed class SetInputContextCommand : IConsoleCommand
{
public string Command => "setinputcontext";
public string Description => "Sets the active input context.";

View File

@@ -4,7 +4,7 @@ using Robust.Shared.GameObjects;
namespace Robust.Client.Console.Commands
{
public class VelocitiesCommand : IConsoleCommand
public sealed class VelocitiesCommand : IConsoleCommand
{
public string Command => "showvelocities";
public string Description => "Displays your angular and linear velocities";

View File

@@ -11,7 +11,7 @@ using static Robust.Shared.Network.Messages.MsgScriptCompletionResponse;
namespace Robust.Client.Console
{
public class Completions : DefaultWindow
public sealed class Completions : DefaultWindow
{
private HistoryLineEdit _textBar;
private ScrollContainer _suggestPanel = new()
@@ -75,7 +75,7 @@ namespace Robust.Client.Console
}
// Label and ghetto button.
public class Entry : RichTextLabel
public sealed class Entry : RichTextLabel
{
public readonly LiteResult Result;

View File

@@ -6,7 +6,7 @@ using Robust.Shared.Network.Messages;
namespace Robust.Client.Console
{
public partial class ScriptClient : IScriptClient
public sealed partial class ScriptClient : IScriptClient
{
[Dependency] private readonly IClientConGroupController _conGroupController = default!;
[Dependency] private readonly IClientNetManager _netManager = default!;

View File

@@ -15,7 +15,7 @@ using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Robust.Client.Console
{
public class WatchWindow : DefaultWindow
public sealed class WatchWindow : DefaultWindow
{
private readonly IReflectionManager _reflectionManager;

View File

@@ -7,7 +7,7 @@ using Robust.Shared.Maths;
namespace Robust.Client.Debugging
{
/// <inheritdoc />
public class DebugDrawing : IDebugDrawing
public sealed class DebugDrawing : IDebugDrawing
{
[Dependency] private readonly IOverlayManager _overlayManager = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;

View File

@@ -209,8 +209,8 @@ namespace Robust.Client.Debugging
foreach (var fixture in _entityManager.GetComponent<FixturesComponent>(physBody.Owner).Fixtures.Values)
{
// Invalid shape - Box2D doesn't check for IsSensor
if (physBody.BodyType == BodyType.Dynamic && fixture.Mass == 0f)
// Invalid shape - Box2D doesn't check for IsSensor but we will for sanity.
if (physBody.BodyType == BodyType.Dynamic && fixture.Mass == 0f && fixture.Hard)
{
DrawShape(worldHandle, fixture, xform, Color.Red.WithAlpha(AlphaModifier));
}

View File

@@ -7,7 +7,7 @@ namespace Robust.Client
{
internal partial class GameController
{
internal class LoaderEntryPoint : ILoaderEntryPoint
internal sealed class LoaderEntryPoint : ILoaderEntryPoint
{
public void Main(IMainArgs args)
{

View File

@@ -3,7 +3,7 @@ using Robust.Shared.Utility;
namespace Robust.Client
{
public class GameControllerOptions
public sealed class GameControllerOptions
{
/// <summary>
/// Whether content sandboxing will be enabled & enforced.

View File

@@ -6,7 +6,7 @@ using Robust.Shared.Reflection;
namespace Robust.Client.GameObjects
{
internal class ClientComponentFactory : ComponentFactory
internal sealed class ClientComponentFactory : ComponentFactory
{
public ClientComponentFactory(IDynamicTypeFactoryInternal typeFactory, IReflectionManager reflectionManager, IConsoleHost conHost)
: base(typeFactory, reflectionManager, conHost)

View File

@@ -4,6 +4,7 @@ using System.Runtime.Serialization;
namespace Robust.Client.GameObjects
{
[Serializable]
[Virtual]
public class ComponentStateApplyException : Exception
{
public ComponentStateApplyException()

View File

@@ -1,4 +1,5 @@
using Robust.Shared.GameObjects;
using System;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Robust.Client.GameObjects;
@@ -14,6 +15,7 @@ public abstract class AppearanceVisualizer
/// Initializes an entity to be managed by this appearance controller.
/// DO NOT assume this is your only entity. Visualizers are shared.
/// </summary>
[Obsolete("Subscribe to your component being initialised instead.")]
public virtual void InitializeEntity(EntityUid entity)
{
}
@@ -23,6 +25,7 @@ public abstract class AppearanceVisualizer
/// Update its visuals here.
/// </summary>
/// <param name="component">The appearance component of the entity that might need updating.</param>
[Obsolete("Subscribe to AppearanceChangeEvent instead.")]
public virtual void OnChangeData(AppearanceComponent component)
{
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
@@ -9,39 +10,10 @@ namespace Robust.Client.GameObjects;
/// This is the client instance of <see cref="AppearanceComponent"/>.
/// </summary>
[RegisterComponent]
[ComponentReference(typeof(AppearanceComponent))]
[ComponentReference(typeof(AppearanceComponent)), Friend(typeof(AppearanceSystem))]
public sealed class ClientAppearanceComponent : AppearanceComponent
{
[ViewVariables]
private bool _appearanceDirty;
[ViewVariables]
[DataField("visuals")]
internal List<AppearanceVisualizer> Visualizers = new();
protected override void MarkDirty()
{
if (_appearanceDirty)
return;
EntitySystem.Get<AppearanceSystem>().EnqueueUpdate(this);
_appearanceDirty = true;
}
protected override void Initialize()
{
base.Initialize();
foreach (var visual in Visualizers)
{
visual.InitializeEntity(Owner);
}
MarkDirty();
}
internal void UnmarkDirty()
{
_appearanceDirty = false;
}
}

View File

@@ -9,7 +9,7 @@ using Robust.Shared.ViewVariables;
namespace Robust.Client.GameObjects
{
[ComponentReference(typeof(SharedEyeComponent))]
public class EyeComponent : SharedEyeComponent
public sealed class EyeComponent : SharedEyeComponent
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;

View File

@@ -12,7 +12,7 @@ using Robust.Shared.Utility;
namespace Robust.Client.GameObjects
{
[RegisterComponent]
public class IconComponent : Component, ISerializationHooks
public sealed class IconComponent : Component, ISerializationHooks
{
public IDirectionalTextureProvider? Icon { get; private set; }

View File

@@ -8,7 +8,7 @@ namespace Robust.Client.GameObjects
/// <summary>
/// Defines data fields used in the <see cref="InputSystem"/>.
/// </summary>
public class InputComponent : Component
public sealed class InputComponent : Component
{
/// <summary>
/// The context that will be made active for a client that attaches to this entity.

View File

@@ -40,13 +40,14 @@ namespace Robust.Client.GameObjects
public void AnchorStateChanged()
{
SendDirty();
var xform = _entityManager.GetComponent<TransformComponent>(Owner);
SendDirty(xform);
if(!_entityManager.GetComponent<TransformComponent>(Owner).Anchored)
if(!xform.Anchored)
return;
var grid = _mapManager.GetGrid(_entityManager.GetComponent<TransformComponent>(Owner).GridID);
_lastPosition = (_entityManager.GetComponent<TransformComponent>(Owner).GridID, grid.TileIndicesFor(_entityManager.GetComponent<TransformComponent>(Owner).Coordinates));
var grid = _mapManager.GetGrid(xform.GridID);
_lastPosition = (xform.GridID, grid.TileIndicesFor(xform.Coordinates));
}
protected override void Shutdown()
@@ -56,9 +57,10 @@ namespace Robust.Client.GameObjects
SendDirty();
}
private void SendDirty()
private void SendDirty(TransformComponent? xform = null)
{
if (_entityManager.GetComponent<TransformComponent>(Owner).Anchored)
xform ??= _entityManager.GetComponent<TransformComponent>(Owner);
if (xform.Anchored)
{
_entityManager.EventBus.RaiseEvent(EventSource.Local,
new OccluderDirtyEvent(Owner, _lastPosition));

View File

@@ -11,7 +11,7 @@ namespace Robust.Client.GameObjects
{
[RegisterComponent]
[ComponentReference(typeof(SharedPointLightComponent))]
public class PointLightComponent : SharedPointLightComponent, ISerializationHooks
public sealed class PointLightComponent : SharedPointLightComponent, ISerializationHooks
{
[Dependency] private readonly IEntityManager _entityManager = default!;
@@ -139,7 +139,7 @@ namespace Robust.Client.GameObjects
internal RenderingTreeComponent? RenderTree { get; set; }
}
public class PointLightRadiusChangedEvent : EntityEventArgs
public sealed class PointLightRadiusChangedEvent : EntityEventArgs
{
public PointLightComponent PointLightComponent { get; }

View File

@@ -57,7 +57,7 @@ namespace Robust.Client.GameObjects
private bool _enabled;
}
public class SpriteBoundsOverlay : Overlay
public sealed class SpriteBoundsOverlay : Overlay
{
public override OverlaySpace Space => OverlaySpace.WorldSpace;

View File

@@ -1615,7 +1615,7 @@ namespace Robust.Client.GameObjects
Flip = 3,
}
public class Layer : ISpriteLayer
public sealed class Layer : ISpriteLayer
{
[ViewVariables] private readonly SpriteComponent _parent;

View File

@@ -11,7 +11,7 @@ using Robust.Shared.ViewVariables;
namespace Robust.Client.GameObjects
{
[ComponentReference(typeof(SharedUserInterfaceComponent))]
public class ClientUserInterfaceComponent : SharedUserInterfaceComponent, ISerializationHooks
public sealed class ClientUserInterfaceComponent : SharedUserInterfaceComponent, ISerializationHooks
{
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
[Dependency] private readonly IDynamicTypeFactory _dynamicTypeFactory = default!;

View File

@@ -62,6 +62,12 @@ namespace Robust.Client.GameObjects
Play(component, animation, key);
}
public void Play(EntityUid uid, AnimationPlayerComponent? component, Animation animation, string key)
{
component ??= EntityManager.EnsureComponent<AnimationPlayerComponent>(uid);
Play(component, animation, key);
}
/// <summary>
/// Start playing an animation.
/// </summary>
@@ -79,6 +85,14 @@ namespace Robust.Client.GameObjects
component.PlayingAnimations.ContainsKey(key);
}
public bool HasRunningAnimation(EntityUid uid, AnimationPlayerComponent? component, string key)
{
if (component == null)
TryComp(uid, out component);
return component != null && component.PlayingAnimations.ContainsKey(key);
}
public bool HasRunningAnimation(AnimationPlayerComponent component, string key)
{
return component.PlayingAnimations.ContainsKey(key);
@@ -88,6 +102,18 @@ namespace Robust.Client.GameObjects
{
component.PlayingAnimations.Remove(key);
}
public void Stop(EntityUid uid, string key)
{
if (!TryComp<AnimationPlayerComponent>(uid, out var player)) return;
player.PlayingAnimations.Remove(key);
}
public void Stop(EntityUid uid, AnimationPlayerComponent? component, string key)
{
if (!Resolve(uid, ref component, false)) return;
component.PlayingAnimations.Remove(key);
}
}
public sealed class AnimationCompletedEvent : EntityEventArgs

View File

@@ -1,17 +1,71 @@
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
namespace Robust.Client.GameObjects
{
[UsedImplicitly]
internal sealed class AppearanceSystem : EntitySystem
internal sealed class AppearanceSystem : SharedAppearanceSystem
{
private readonly Queue<ClientAppearanceComponent> _queuedUpdates = new();
public void EnqueueUpdate(ClientAppearanceComponent component)
public override void Initialize()
{
_queuedUpdates.Enqueue(component);
base.Initialize();
SubscribeLocalEvent<ClientAppearanceComponent, ComponentInit>(OnAppearanceInit);
SubscribeLocalEvent<ClientAppearanceComponent, ComponentHandleState>(OnAppearanceHandleState);
}
private void OnAppearanceInit(EntityUid uid, ClientAppearanceComponent component, ComponentInit args)
{
foreach (var visual in component.Visualizers)
{
visual.InitializeEntity(uid);
}
MarkDirty(component);
}
private void OnAppearanceHandleState(EntityUid uid, ClientAppearanceComponent component, ref ComponentHandleState args)
{
if (args.Current is not AppearanceComponentState actualState)
return;
var stateDiff = component.AppearanceData.Count != actualState.Data.Count;
if (!stateDiff)
{
foreach (var (key, value) in component.AppearanceData)
{
if (!actualState.Data.TryGetValue(key, out var stateValue) ||
!value.Equals(stateValue))
{
stateDiff = true;
break;
}
}
}
if (!stateDiff) return;
component.AppearanceData = actualState.Data;
MarkDirty(component);
}
public override void MarkDirty(AppearanceComponent component)
{
if (component.AppearanceDirty)
return;
_queuedUpdates.Enqueue((ClientAppearanceComponent) component);
component.AppearanceDirty = true;
}
internal void UnmarkDirty(ClientAppearanceComponent component)
{
component.AppearanceDirty = false;
}
public override void FrameUpdate(float frameTime)
@@ -22,7 +76,7 @@ namespace Robust.Client.GameObjects
continue;
OnChangeData(appearance.Owner, appearance);
appearance.UnmarkDirty();
UnmarkDirty(appearance);
}
}
@@ -30,10 +84,30 @@ namespace Robust.Client.GameObjects
{
if (!Resolve(uid, ref appearanceComponent, false)) return;
var ev = new AppearanceChangeEvent
{
Component = appearanceComponent,
AppearanceData = appearanceComponent.AppearanceData,
};
// Give it AppearanceData so we can still keep the friend attribute on the component.
EntityManager.EventBus.RaiseLocalEvent(uid, ref ev);
// Eventually visualizers would be nuked and we'd just make them components instead.
foreach (var visualizer in appearanceComponent.Visualizers)
{
visualizer.OnChangeData(appearanceComponent);
}
}
}
/// <summary>
/// Raised whenever the appearance data for an entity changes.
/// </summary>
[ByRefEvent]
public struct AppearanceChangeEvent
{
public AppearanceComponent Component = default!;
public IReadOnlyDictionary<object, object> AppearanceData = default!;
}
}

View File

@@ -17,7 +17,7 @@ using Robust.Shared.Utility;
namespace Robust.Client.GameObjects
{
[UsedImplicitly]
public class AudioSystem : SharedAudioSystem, IAudioSystem
public sealed class AudioSystem : SharedAudioSystem, IAudioSystem
{
[Dependency] private readonly IResourceCache _resourceCache = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
@@ -420,7 +420,7 @@ namespace Robust.Client.GameObjects
source.IsLooping = audioParams.Value.Loop;
}
private class PlayingStream : IPlayingAudioStream
private sealed class PlayingStream : IPlayingAudioStream
{
public uint? NetIdentifier;
public IClydeAudioSource Source = default!;

View File

@@ -74,8 +74,11 @@ namespace Robust.Client.GameObjects
EntityManager.TryGetComponent(sender, out ClientOccluderComponent? iconSmooth)
&& iconSmooth.Initialized)
{
var grid1 = _mapManager.GetGrid(EntityManager.GetComponent<TransformComponent>(sender).GridID);
var coords = EntityManager.GetComponent<TransformComponent>(sender).Coordinates;
var xform = EntityManager.GetComponent<TransformComponent>(sender);
if (!_mapManager.TryGetGrid(xform.GridID, out var grid1))
return;
var coords = xform.Coordinates;
_dirtyEntities.Enqueue(sender);
AddValidEntities(grid1.GetInDir(coords, Direction.North));

View File

@@ -5,12 +5,14 @@ using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Serialization;
using static Robust.Shared.Containers.ContainerManagerComponent;
namespace Robust.Client.GameObjects
{
public class ContainerSystem : SharedContainerSystem
public sealed class ContainerSystem : SharedContainerSystem
{
[Dependency] private readonly IRobustSerializer _serializer = default!;
[Dependency] private readonly IDynamicTypeFactoryInternal _dynFactory = default!;
@@ -59,7 +61,7 @@ namespace Robust.Client.GameObjects
{
if (!cast.ContainerSet.Any(data => data.Id == id))
{
container.EmptyContainer(true);
container.EmptyContainer(true, entMan: EntityManager);
container.Shutdown();
toDelete ??= new List<string>();
toDelete.Add(id);
@@ -131,12 +133,51 @@ namespace Robust.Client.GameObjects
continue;
}
// If an entity is currently in the shadow realm, it means we probably left PVS and are now getting
// back into range. We do not want to directly insert this entity, as IF the container and entity
// transform states did not get sent simultaneously, the entity's transform will be modified by the
// insert operation. This means it will then be reset to the shadow realm, causing it to be ejected
// from the container. It would then subsequently be parented to the container without ever being
// re-inserted, leading to the client seeing what should be hidden entities attached to
// containers/players.
if (Transform(entity).MapID == MapId.Nullspace)
{
AddExpectedEntity(entity, container);
continue;
}
if (!container.ContainedEntities.Contains(entity))
container.Insert(entity);
}
}
}
protected override void HandleParentChanged(ref EntParentChangedMessage message)
{
base.HandleParentChanged(ref message);
// If an entity warped in from null-space (i.e., re-entered PVS) and got attached to a container, do the same checks as for newly initialized entities.
if (message.OldParent != null && message.OldParent.Value.IsValid())
return;
if (!ExpectedEntities.TryGetValue(message.Entity, out var container))
return;
if (Transform(message.Entity).ParentUid != container.Owner)
{
// This container is expecting an entity... but it got parented to some other entity???
// Ah well, the sever should send a new container state that updates expected entities so just ignore it for now.
return;
}
RemoveExpectedEntity(message.Entity);
if (container.Deleted)
return;
container.Insert(message.Entity);
}
private IContainer ContainerFactory(ContainerManagerComponent component, string containerType, string id)
{
var type = _serializer.FindSerializedType(typeof(IContainer), containerType);

View File

@@ -15,7 +15,7 @@ using Robust.Shared.Enums;
namespace Robust.Client.GameObjects
{
public class EffectSystem : EntitySystem
public sealed class EffectSystem : EntitySystem
{
[Dependency] private readonly IGameTiming gameTiming = default!;
[Dependency] private readonly IResourceCache resourceCache = default!;
@@ -94,7 +94,7 @@ namespace Robust.Client.GameObjects
}
}
private class Effect
private sealed class Effect
{
/// <summary>
/// Effect Sprite

View File

@@ -20,7 +20,7 @@ namespace Robust.Client.GameObjects
/// Updates the position of every Eye every frame, so that the camera follows the player around.
/// </summary>
[UsedImplicitly]
public class EyeUpdateSystem : EntitySystem
public sealed class EyeUpdateSystem : EntitySystem
{
/// <inheritdoc />
public override void Initialize()

View File

@@ -10,7 +10,7 @@ using Robust.Shared.Utility;
namespace Robust.Client.GameObjects
{
public class GridChunkBoundsDebugSystem : EntitySystem
public sealed class GridChunkBoundsDebugSystem : EntitySystem
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;

View File

@@ -16,7 +16,7 @@ namespace Robust.Client.GameObjects
/// <summary>
/// Client-side processing of all input commands through the simulation.
/// </summary>
public class InputSystem : SharedInputSystem
public sealed class InputSystem : SharedInputSystem
{
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
@@ -163,7 +163,7 @@ namespace Robust.Client.GameObjects
/// <summary>
/// Entity system message that is raised when the player changes attached entities.
/// </summary>
public class PlayerAttachSysMessage : EntityEventArgs
public sealed class PlayerAttachSysMessage : EntityEventArgs
{
/// <summary>
/// New entity the player is attached to.
@@ -180,7 +180,7 @@ namespace Robust.Client.GameObjects
}
}
public class PlayerAttachedEvent : EntityEventArgs
public sealed class PlayerAttachedEvent : EntityEventArgs
{
public PlayerAttachedEvent(EntityUid entity)
{
@@ -190,7 +190,7 @@ namespace Robust.Client.GameObjects
public EntityUid Entity { get; }
}
public class PlayerDetachedEvent : EntityEventArgs
public sealed class PlayerDetachedEvent : EntityEventArgs
{
public PlayerDetachedEvent(EntityUid entity)
{

View File

@@ -4,7 +4,7 @@ using Robust.Shared.IoC;
namespace Robust.Client.GameObjects
{
public class MidiSystem : EntitySystem
public sealed class MidiSystem : EntitySystem
{
[Dependency] private readonly IMidiManager _midiManager = default!;

View File

@@ -113,10 +113,12 @@ namespace Robust.Client.GameObjects
private void AnythingMoved(ref MoveEvent args)
{
AnythingMovedSubHandler(args.Sender);
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
AnythingMovedSubHandler(args.Sender, xforms);
}
private void AnythingMovedSubHandler(EntityUid uid, TransformComponent? xform = null)
private void AnythingMovedSubHandler(EntityUid uid, EntityQuery<TransformComponent> xforms)
{
// To avoid doing redundant updates (and we don't need to update a grid's children ever)
if (!_checkedChildren.Add(uid) || EntityManager.HasComponent<RenderingTreeComponent>(uid)) return;
@@ -131,11 +133,11 @@ namespace Robust.Client.GameObjects
if (EntityManager.TryGetComponent(uid, out PointLightComponent? light))
QueueLightUpdate(light);
if (!Resolve(uid, ref xform)) return;
if (!xforms.TryGetComponent(uid, out var xform)) return;
foreach (var child in xform.ChildEntities)
{
AnythingMovedSubHandler(child);
AnythingMovedSubHandler(child, xforms);
}
}
@@ -248,23 +250,21 @@ namespace Robust.Client.GameObjects
EntityManager.EnsureComponent<RenderingTreeComponent>(_mapManager.GetGrid(gridId).GridEntityId);
}
// TODO: Pass in TransformComponent directly: mainly interested in getting this shit working atm.
private RenderingTreeComponent? GetRenderTree(EntityUid entity)
private RenderingTreeComponent? GetRenderTree(EntityUid entity, EntityQuery<TransformComponent> xforms)
{
var lookups = EntityManager.GetEntityQuery<RenderingTreeComponent>();
if (!EntityManager.EntityExists(entity) ||
!EntityManager.TryGetComponent(entity, out TransformComponent? xform) ||
!xforms.TryGetComponent(entity, out var xform) ||
xform.MapID == MapId.Nullspace ||
EntityManager.HasComponent<RenderingTreeComponent>(entity)) return null;
lookups.HasComponent(entity)) return null;
var parent = xform.ParentUid;
while (true)
while (parent.IsValid())
{
if (!parent.IsValid())
break;
if (EntityManager.TryGetComponent(parent, out RenderingTreeComponent? comp)) return comp;
parent = EntityManager.GetComponent<TransformComponent>(parent).ParentUid;
if (lookups.TryGetComponent(parent, out var comp)) return comp;
parent = xforms.GetComponent(parent).ParentUid;
}
return null;
@@ -279,6 +279,8 @@ namespace Robust.Client.GameObjects
{
_checkedChildren.Clear();
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
foreach (var sprite in _spriteQueue)
{
sprite.TreeUpdateQueued = false;
@@ -289,9 +291,9 @@ namespace Robust.Client.GameObjects
}
var oldMapTree = sprite.RenderTree;
var newMapTree = GetRenderTree(sprite.Owner);
var newMapTree = GetRenderTree(sprite.Owner, xforms);
// TODO: Temp PVS guard
var xform = EntityManager.GetComponent<TransformComponent>(sprite.Owner);
var xform = xforms.GetComponent(sprite.Owner);
var (worldPos, worldRot) = xform.GetWorldPositionRotation();
if (float.IsNaN(worldPos.X) || float.IsNaN(worldPos.Y))
@@ -300,7 +302,7 @@ namespace Robust.Client.GameObjects
continue;
}
var aabb = SpriteAabbFunc(sprite, worldPos, worldRot);
var aabb = SpriteAabbFunc(sprite, worldPos, worldRot, xforms);
// If we're on a new map then clear the old one.
if (oldMapTree != newMapTree)
@@ -327,9 +329,9 @@ namespace Robust.Client.GameObjects
}
var oldMapTree = light.RenderTree;
var newMapTree = GetRenderTree(light.Owner);
var newMapTree = GetRenderTree(light.Owner, xforms);
// TODO: Temp PVS guard
var worldPos = EntityManager.GetComponent<TransformComponent>(light.Owner).WorldPosition;
var worldPos = xforms.GetComponent(light.Owner).WorldPosition;
if (float.IsNaN(worldPos.X) || float.IsNaN(worldPos.Y))
{
@@ -344,7 +346,7 @@ namespace Robust.Client.GameObjects
Logger.WarningS(LoggerSawmill, $"Light radius for {light.Owner} set above max radius of {MaxLightRadius}. This may lead to pop-in.");
}
var aabb = LightAabbFunc(light, worldPos);
var aabb = LightAabbFunc(light, worldPos, xforms);
// If we're on a new map then clear the old one.
if (oldMapTree != newMapTree)
@@ -366,69 +368,43 @@ namespace Robust.Client.GameObjects
private Box2 SpriteAabbFunc(in SpriteComponent value)
{
var xform = EntityManager.GetComponent<TransformComponent>(value.Owner);
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
var xform = xforms.GetComponent(value.Owner);
var (worldPos, worldRot) = xform.GetWorldPositionRotation();
var bounds = new Box2Rotated(value.CalculateBoundingBox(worldPos), worldRot, worldPos);
var tree = GetRenderTree(value.Owner);
var tree = GetRenderTree(value.Owner, xforms);
if (tree == null)
{
return bounds.CalcBoundingBox();
}
else
{
return EntityManager.GetComponent<TransformComponent>(tree.Owner).InvWorldMatrix.TransformBox(bounds);
}
return tree == null ? bounds.CalcBoundingBox() : xforms.GetComponent(tree.Owner).InvWorldMatrix.TransformBox(bounds);
}
private Box2 LightAabbFunc(in PointLightComponent value)
{
var worldPos = EntityManager.GetComponent<TransformComponent>(value.Owner).WorldPosition;
var tree = GetRenderTree(value.Owner);
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
var worldPos = xforms.GetComponent(value.Owner).WorldPosition;
var tree = GetRenderTree(value.Owner, xforms);
var boxSize = value.Radius * 2;
Vector2 localPos;
if (tree == null)
{
localPos = worldPos;
}
else
{
// TODO: Need a way to just cache this InvWorldMatrix
localPos = EntityManager.GetComponent<TransformComponent>(tree.Owner).InvWorldMatrix.Transform(worldPos);
}
var localPos = tree == null ? worldPos : xforms.GetComponent(tree.Owner).InvWorldMatrix.Transform(worldPos);
return Box2.CenteredAround(localPos, (boxSize, boxSize));
}
private Box2 SpriteAabbFunc(SpriteComponent value, Vector2 worldPos, Angle worldRot)
private Box2 SpriteAabbFunc(SpriteComponent value, Vector2 worldPos, Angle worldRot, EntityQuery<TransformComponent> xforms)
{
var bounds = new Box2Rotated(value.CalculateBoundingBox(worldPos), worldRot, worldPos);
var tree = GetRenderTree(value.Owner);
var tree = GetRenderTree(value.Owner, xforms);
if (tree == null)
{
return bounds.CalcBoundingBox();
}
else
{
return EntityManager.GetComponent<TransformComponent>(tree.Owner).InvWorldMatrix.TransformBox(bounds);
}
return tree == null ? bounds.CalcBoundingBox() : xforms.GetComponent(tree.Owner).InvWorldMatrix.TransformBox(bounds);
}
private Box2 LightAabbFunc(PointLightComponent value, Vector2 worldPos)
private Box2 LightAabbFunc(PointLightComponent value, Vector2 worldPos, EntityQuery<TransformComponent> xforms)
{
// Lights are circles so don't need entity's rotation
var tree = GetRenderTree(value.Owner);
var tree = GetRenderTree(value.Owner, xforms);
var boxSize = value.Radius * 2;
Vector2 localPos;
if (tree == null)
{
localPos = worldPos;
} else
{
localPos = EntityManager.GetComponent<TransformComponent>(tree.Owner).InvWorldMatrix.Transform(worldPos);
}
var localPos = tree == null ? worldPos : xforms.GetComponent(tree.Owner).InvWorldMatrix.Transform(worldPos);
return Box2.CenteredAround(localPos, (boxSize, boxSize));
}
}

View File

@@ -11,7 +11,7 @@ namespace Robust.Client.GameObjects
/// Updates the layer animation for every visible sprite.
/// </summary>
[UsedImplicitly]
public class SpriteSystem : EntitySystem
public sealed class SpriteSystem : EntitySystem
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly RenderingTreeSystem _treeSystem = default!;
@@ -53,9 +53,11 @@ namespace Robust.Client.GameObjects
return;
}
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
foreach (var comp in _treeSystem.GetRenderTrees(currentMap, pvsBounds))
{
var bounds = EntityManager.GetComponent<TransformComponent>(comp.Owner).InvWorldMatrix.TransformBox(pvsBounds);
var bounds = xforms.GetComponent(comp.Owner).InvWorldMatrix.TransformBox(pvsBounds);
comp.SpriteTree.QueryAabb(ref frameTime, (ref float state, in SpriteComponent value) =>
{

View File

@@ -8,7 +8,7 @@ using Robust.Shared.Maths;
namespace Robust.Client.GameObjects
{
public class VelocityDebugSystem : EntitySystem
public sealed class VelocityDebugSystem : EntitySystem
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;

View File

@@ -0,0 +1,20 @@
using Robust.Shared.GameObjects;
namespace Robust.Client.GameObjects;
/// <summary>
/// An abstract entity system inheritor for systems that deal with
/// appearance data, replacing <see cref="AppearanceVisualizer"/>.
/// </summary>
public abstract class VisualizerSystem<T> : EntitySystem
where T: Component
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<T, AppearanceChangeEvent>(OnAppearanceChange);
}
protected virtual void OnAppearanceChange(EntityUid uid, T component, ref AppearanceChangeEvent args) {}
}

View File

@@ -28,7 +28,7 @@ namespace Robust.Client.GameStates
{
/// <inheritdoc />
[UsedImplicitly]
public class ClientGameStateManager : IClientGameStateManager
public sealed class ClientGameStateManager : IClientGameStateManager
{
private GameStateProcessor _processor = default!;
@@ -637,7 +637,7 @@ namespace Robust.Client.GameStates
}
}
public class GameStateAppliedArgs : EventArgs
public sealed class GameStateAppliedArgs : EventArgs
{
public GameState AppliedState { get; }

View File

@@ -10,7 +10,7 @@ using Robust.Shared.Utility;
namespace Robust.Client.GameStates
{
/// <inheritdoc />
internal class GameStateProcessor : IGameStateProcessor
internal sealed class GameStateProcessor : IGameStateProcessor
{
private readonly IGameTiming _timing;

View File

@@ -19,7 +19,7 @@ namespace Robust.Client.GameStates
/// A network entity report that lists all entities as they are updated through game states.
/// https://developer.valvesoftware.com/wiki/Networking_Entities#cl_entityreport
/// </summary>
class NetEntityOverlay : Overlay
sealed class NetEntityOverlay : Overlay
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IClientNetManager _netManager = default!;
@@ -244,7 +244,7 @@ namespace Robust.Client.GameStates
}
}
private class NetEntityReportCommand : IConsoleCommand
private sealed class NetEntityReportCommand : IConsoleCommand
{
public string Command => "net_entityreport";
public string Help => "net_entityreport <0|1>";

View File

@@ -16,7 +16,7 @@ namespace Robust.Client.GameStates
/// <summary>
/// Visual debug overlay for the network diagnostic graph.
/// </summary>
internal class NetGraphOverlay : Overlay
internal sealed class NetGraphOverlay : Overlay
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IClientNetManager _netManager = default!;
@@ -239,7 +239,7 @@ namespace Robust.Client.GameStates
base.DisposeBehavior();
}
private class NetShowGraphCommand : IConsoleCommand
private sealed class NetShowGraphCommand : IConsoleCommand
{
public string Command => "net_graph";
public string Help => "net_graph <0|1>";
@@ -275,7 +275,7 @@ namespace Robust.Client.GameStates
}
}
private class NetWatchEntCommand : IConsoleCommand
private sealed class NetWatchEntCommand : IConsoleCommand
{
public string Command => "net_watchent";
public string Help => "net_watchent <0|EntityUid>";

View File

@@ -11,7 +11,7 @@ using Robust.Shared.Timing;
namespace Robust.Client.GameStates
{
internal class NetInterpOverlay : Overlay
internal sealed class NetInterpOverlay : Overlay
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
@@ -38,7 +38,7 @@ namespace Robust.Client.GameStates
var transform = _entityManager.GetComponent<TransformComponent>(boundingBox.Owner);
// if not on the same map, continue
if (transform.MapID != _eyeManager.CurrentMap || boundingBox.Owner.IsInContainer())
if (transform.MapID != _eyeManager.CurrentMap || boundingBox.Owner.IsInContainer(_entityManager))
continue;
// This entity isn't lerping, no need to draw debug info for it
@@ -65,7 +65,7 @@ namespace Robust.Client.GameStates
}
}
private class NetShowInterpCommand : IConsoleCommand
private sealed class NetShowInterpCommand : IConsoleCommand
{
public string Command => "net_draw_interp";
public string Help => "net_draw_interp <0|1>";

View File

@@ -18,7 +18,7 @@ using Vector2 = Robust.Shared.Maths.Vector2;
namespace Robust.Client.Graphics.Audio
{
internal partial class ClydeAudio : IClydeAudio, IClydeAudioInternal
internal sealed partial class ClydeAudio : IClydeAudio, IClydeAudioInternal
{
private ALDevice _openALDevice;
private ALContext _openALContext;
@@ -224,7 +224,7 @@ namespace Robust.Client.Graphics.Audio
_openALSawmill.Error("Failed to generate source. Too many simultaneous audio streams?");
return null;
}
// ReSharper disable once PossibleInvalidOperationException
// TODO: This really shouldn't be indexing based on the ClydeHandle...
AL.Source(source, ALSourcei.Buffer, _audioSampleBuffers[(int) stream.ClydeHandle!.Value.Value].BufferHandle);

View File

@@ -18,6 +18,7 @@ namespace Robust.Client.Graphics.Audio
/// <summary>
/// Hey look, it's ClydeAudio.AudioSource's evil twin brother!
/// </summary>
[Virtual]
internal class DummyAudioSource : IClydeAudioSource
{
public static DummyAudioSource Instance { get; } = new();

View File

@@ -7,6 +7,7 @@ using Robust.Shared.ViewVariables;
namespace Robust.Client.Graphics
{
/// <inheritdoc />
[Virtual]
public class Eye : IEye
{
private Vector2 _scale = Vector2.One/2f;

View File

@@ -153,7 +153,7 @@ namespace Robust.Client.Graphics
}
}
public class CurrentEyeChangedEvent : EntityEventArgs
public sealed class CurrentEyeChangedEvent : EntityEventArgs
{
public IEye? Old { get; }
public IEye New { get; }

View File

@@ -3,7 +3,7 @@
/// <summary>
/// A fixed eye is an eye which is fixed to one point, its position.
/// </summary>
public class FixedEye : Eye
public sealed class FixedEye : Eye
{
}
}

View File

@@ -214,7 +214,7 @@ namespace Robust.Client.Graphics.Clyde
_mapChunkData.Remove(gridId);
}
private class MapChunkData
private sealed class MapChunkData
{
public bool Dirty;
public readonly uint VAO;

View File

@@ -372,22 +372,24 @@ namespace Robust.Client.Graphics.Clyde
private void ProcessSpriteEntities(MapId map, Matrix3 eyeMatrix, Box2Rotated worldBounds,
RefList<(SpriteComponent sprite, Matrix3 matrix, Angle worldRot, float yWorldPos)> list)
{
var xforms = _entityManager.GetEntityQuery<TransformComponent>();
foreach (var comp in _entitySystemManager.GetEntitySystem<RenderingTreeSystem>().GetRenderTrees(map, worldBounds))
{
var bounds = _entityManager.GetComponent<TransformComponent>(comp.Owner).InvWorldMatrix.TransformBox(worldBounds);
var bounds = xforms.GetComponent(comp.Owner).InvWorldMatrix.TransformBox(worldBounds);
comp.SpriteTree.QueryAabb(ref list, (
ref RefList<(SpriteComponent sprite, Matrix3 matrix, Angle worldRot, float yWorldPos)> state,
in SpriteComponent value) =>
{
var entity = value.Owner;
var transform = _entityManager.GetComponent<TransformComponent>(entity);
var transform = xforms.GetComponent(entity);
ref var entry = ref state.AllocAdd();
entry.sprite = value;
entry.worldRot = transform.WorldRotation;
entry.matrix = transform.WorldMatrix;
var eyePos = eyeMatrix.Transform(new Vector2(entry.matrix.R0C2, entry.matrix.R1C2));
Vector2 worldPos;
(worldPos, entry.worldRot, entry.matrix) = transform.GetWorldPositionRotationMatrix();
var eyePos = eyeMatrix.Transform(worldPos);
// Didn't use the bounds from the query as that has to be re-calculated (and is probably more expensive than this).
var bounds = value.CalculateBoundingBox(eyePos);
entry.yWorldPos = eyePos.Y - bounds.Extents.Y;

View File

@@ -515,10 +515,11 @@ namespace Robust.Client.Graphics.Clyde
// Use worldbounds for this one as we only care if the light intersects our actual bounds
var state = (this, worldAABB, count: 0);
var xforms = _entityManager.GetEntityQuery<TransformComponent>();
foreach (var comp in renderingTreeSystem.GetRenderTrees(map, enlargedBounds))
{
var bounds = _entityManager.GetComponent<TransformComponent>(comp.Owner).InvWorldMatrix.TransformBox(worldBounds);
var bounds = xforms.GetComponent(comp.Owner).InvWorldMatrix.TransformBox(worldBounds);
comp.LightTree.QueryAabb(ref state, (ref (Clyde clyde, Box2 worldAABB, int count) state, in PointLightComponent light) =>
{
@@ -528,7 +529,7 @@ namespace Robust.Client.Graphics.Clyde
return false;
}
var transform = _entityManager.GetComponent<TransformComponent>(light.Owner);
var transform = xforms.GetComponent(light.Owner);
if (float.IsNaN(transform.LocalPosition.X) || float.IsNaN(transform.LocalPosition.Y)) return true;
@@ -871,21 +872,24 @@ namespace Robust.Client.Graphics.Clyde
var ii = 0;
var imi = 0;
var xforms = _entityManager.GetEntityQuery<TransformComponent>();
foreach (var comp in occluderSystem.GetOccluderTrees(map, expandedBounds))
{
var treeBounds = _entityManager.GetComponent<TransformComponent>(comp.Owner).InvWorldMatrix.TransformBox(expandedBounds);
var treeBounds = xforms.GetComponent(comp.Owner).InvWorldMatrix.TransformBox(expandedBounds);
comp.Tree.QueryAabb((in OccluderComponent sOccluder) =>
{
var occluder = (ClientOccluderComponent)sOccluder;
var transform = _entityManager.GetComponent<TransformComponent>(occluder.Owner);
if (!occluder.Enabled)
var transform = xforms.GetComponent(sOccluder.Owner);
if (!sOccluder.Enabled)
{
return true;
}
var occluder = (ClientOccluderComponent)sOccluder;
var worldTransform = transform.WorldMatrix;
var box = occluder.BoundingBox;
var box = sOccluder.BoundingBox;
var tl = worldTransform.Transform(box.TopLeft);
var tr = worldTransform.Transform(box.TopRight);

View File

@@ -34,7 +34,7 @@ namespace Robust.Client.Graphics.Clyde
private readonly ConcurrentQueue<ClydeHandle> _deadShaderInstances = new();
private class LoadedShader
private sealed class LoadedShader
{
public GLShaderProgram Program = default!;
public bool HasLighting = true;
@@ -42,7 +42,7 @@ namespace Robust.Client.Graphics.Clyde
public string? Name;
}
private class LoadedShaderInstance
private sealed class LoadedShaderInstance
{
public ClydeHandle ShaderHandle;

View File

@@ -144,7 +144,7 @@ namespace Robust.Client.Graphics.Clyde
if (Eye == null)
return default;
var eye = (IEye) Eye;
var eye = Eye;
var newPoint = point;
eye.GetViewMatrix(out var viewMatrix, RenderScale);

View File

@@ -246,7 +246,7 @@ namespace Robust.Client.Graphics.Clyde
// Nada.
}
private class DummyCursor : ICursor
private sealed class DummyCursor : ICursor
{
public void Dispose()
{
@@ -254,6 +254,7 @@ namespace Robust.Client.Graphics.Clyde
}
}
[Virtual]
private class DummyAudioSource : IClydeAudioSource
{
public static DummyAudioSource Instance { get; } = new();

View File

@@ -11,6 +11,7 @@ namespace Robust.Client.Graphics.Clyde
/// <summary>
/// Represents an OpenGL buffer object.
/// </summary>
[Virtual]
private class GLBuffer
{
private readonly Clyde _clyde;
@@ -178,7 +179,7 @@ namespace Robust.Client.Graphics.Clyde
/// Subtype of buffers so that we can have a generic constructor.
/// Functionally equivalent to <see cref="GLBuffer"/> otherwise.
/// </summary>
private class GLBuffer<T> : GLBuffer where T : unmanaged
private sealed class GLBuffer<T> : GLBuffer where T : unmanaged
{
public GLBuffer(Clyde clyde, BufferTarget type, BufferUsageHint usage, Span<T> initialize,
string? name = null)

View File

@@ -4,7 +4,7 @@ namespace Robust.Client.Graphics.Clyde
{
internal partial class Clyde
{
private class GLShader
private sealed class GLShader
{
private readonly Clyde _clyde;

View File

@@ -14,7 +14,7 @@ namespace Robust.Client.Graphics.Clyde
/// You've been warned:
/// using things like <see cref="SetUniformTexture" /> if this buffer isn't bound WILL mess things up!
/// </summary>
private class GLShaderProgram
private sealed class GLShaderProgram
{
private readonly sbyte?[] _uniformIntCache = new sbyte?[UniCount];
private readonly Dictionary<string, int> _uniformCache = new();

View File

@@ -20,7 +20,7 @@ namespace Robust.Client.Graphics.Clyde
/// <summary>
/// Represents some set of uniforms that can be backed by a uniform buffer or by regular uniforms.
/// </summary>
private class GLUniformBuffer<T> where T : unmanaged, IAppliableUniformSet
private sealed class GLUniformBuffer<T> where T : unmanaged, IAppliableUniformSet
{
private readonly Clyde _clyde;
private readonly int _index;

View File

@@ -6,6 +6,7 @@ namespace Robust.Client.Graphics.Clyde
{
[Serializable]
[PublicAPI]
[Virtual]
internal class ShaderCompilationException : Exception
{
public ShaderCompilationException()

View File

@@ -104,6 +104,7 @@ namespace Robust.Client.Graphics.Clyde
}
[Serializable]
[Virtual]
public class GlfwException : Exception
{
public GlfwException()

View File

@@ -2,7 +2,7 @@ using Robust.Shared.Maths;
namespace Robust.Client.Graphics
{
public class StyleBoxEmpty : StyleBox
public sealed class StyleBoxEmpty : StyleBox
{
protected override void DoDraw(DrawingHandleScreen handle, UIBox2 box)
{

View File

@@ -3,7 +3,7 @@ using Robust.Shared.Maths;
namespace Robust.Client.Graphics
{
public class StyleBoxFlat : StyleBox
public sealed class StyleBoxFlat : StyleBox
{
public Color BackgroundColor { get; set; }
public Color BorderColor { get; set; }

View File

@@ -7,7 +7,7 @@ namespace Robust.Client.Graphics
/// <summary>
/// Style box based on a 9-patch texture.
/// </summary>
public class StyleBoxTexture : StyleBox
public sealed class StyleBoxTexture : StyleBox
{
public StyleBoxTexture()
{

View File

@@ -219,7 +219,7 @@ namespace Robust.Client.Graphics
return bitmapImage;
}
private class FontFaceHandle : IFontFaceHandle
private sealed class FontFaceHandle : IFontFaceHandle
{
public Face Face { get; }
@@ -230,7 +230,7 @@ namespace Robust.Client.Graphics
}
[PublicAPI]
private class FontInstanceHandle : IFontInstanceHandle
private sealed class FontInstanceHandle : IFontInstanceHandle
{
public FontFaceHandle FaceHandle { get; }
public int Size { get; }
@@ -325,7 +325,7 @@ namespace Robust.Client.Graphics
}
}
private class ScaledFontData
private sealed class ScaledFontData
{
public ScaledFontData(int ascent, int descent, int height, int lineHeight)
{

View File

@@ -6,7 +6,7 @@ using Robust.Shared.Timing;
namespace Robust.Client.Graphics
{
internal class OverlayManager : IOverlayManagerInternal
internal sealed class OverlayManager : IOverlayManagerInternal
{
private readonly Dictionary<Type, Overlay> _overlays = new Dictionary<Type, Overlay>();
public IEnumerable<Overlay> AllOverlays => _overlays.Values;

View File

@@ -192,7 +192,7 @@ namespace Robust.Client.Graphics
}
[DataDefinition]
public class StencilData
public sealed class StencilData
{
[DataField("ref")] public int StencilRef;

View File

@@ -53,6 +53,7 @@ namespace Robust.Client.Input
}
}
[Virtual]
public class TextEventArgs : EventArgs
{
public TextEventArgs(uint codePoint)
@@ -64,6 +65,7 @@ namespace Robust.Client.Input
public Rune AsRune => new Rune(CodePoint);
}
[Virtual]
public class KeyEventArgs : ModifierInputEventArgs
{
/// <summary>
@@ -104,7 +106,7 @@ namespace Robust.Client.Input
}
}
public class MouseButtonEventArgs : MouseEventArgs
public sealed class MouseButtonEventArgs : MouseEventArgs
{
/// <summary>
/// The mouse button that has been pressed or released.
@@ -119,7 +121,7 @@ namespace Robust.Client.Input
}
}
public class MouseWheelEventArgs : MouseEventArgs
public sealed class MouseWheelEventArgs : MouseEventArgs
{
/// <summary>
/// The direction the mouse wheel was moved in.
@@ -134,7 +136,7 @@ namespace Robust.Client.Input
}
}
public class MouseMoveEventArgs : MouseEventArgs
public sealed class MouseMoveEventArgs : MouseEventArgs
{
/// <summary>
/// The new position relative to the previous position.
@@ -149,7 +151,7 @@ namespace Robust.Client.Input
}
}
public class MouseEnterLeaveEventArgs : EventArgs
public sealed class MouseEnterLeaveEventArgs : EventArgs
{
public IClydeWindow Window { get; }

View File

@@ -31,6 +31,7 @@ using static Robust.Client.Input.Keyboard;
namespace Robust.Client.Input
{
[Virtual]
internal class InputManager : IInputManager
{
// This is for both userdata and resources.
@@ -698,7 +699,7 @@ namespace Robust.Client.Input
}
[DebuggerDisplay("KeyBinding {" + nameof(Function) + "}")]
private class KeyBinding : IKeyBinding
private sealed class KeyBinding : IKeyBinding
{
private readonly InputManager _inputManager;
@@ -906,7 +907,7 @@ namespace Robust.Client.Input
}
[UsedImplicitly]
internal class BindCommand : IConsoleCommand
internal sealed class BindCommand : IConsoleCommand
{
public string Command => "bind";
public string Description => "Binds an input key to an input command.";
@@ -960,7 +961,7 @@ namespace Robust.Client.Input
}
[UsedImplicitly]
internal class SaveBindCommand : IConsoleCommand
internal sealed class SaveBindCommand : IConsoleCommand
{
public string Command => "svbind";
public string Description => "";

View File

@@ -4,7 +4,7 @@ using Robust.Shared.Serialization.Manager.Attributes;
namespace Robust.Client.Input
{
[DataDefinition]
public class KeyBindingRegistration
public sealed class KeyBindingRegistration
{
[DataField("function")]
public BoundKeyFunction Function;

View File

@@ -9,7 +9,7 @@ namespace Robust.Client.Log
/// <summary>
/// Writes logs to the in-game debug console.
/// </summary>
class DebugConsoleLogHandler : ILogHandler
sealed class DebugConsoleLogHandler : ILogHandler
{
readonly IClientConsoleHost Console;

View File

@@ -9,7 +9,7 @@ using Robust.Shared.Timing;
namespace Robust.Client.Physics
{
[UsedImplicitly]
public class PhysicsSystem : SharedPhysicsSystem
public sealed class PhysicsSystem : SharedPhysicsSystem
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IClientGameStateManager _gameState = default!;

Some files were not shown because too many files have changed in this diff Show More