Skip to content

Commit 80f9f24

Browse files
PaulRitterPaulDrSmugleafgradientvera
authored
Serialization v3 aka constant suffering (space-wizards#1606)
* oops * fixes serialization il * copytest * typo & misc fixes * 139 moment * boxing * mesa dum * stuff * goodbye bad friend * last commit before the big (4) rewrite * adds datanodes * kills yamlobjserializer in favor of the new system * adds more serializers, actually implements them & removes most of the last of the old system * changed yamlfieldattribute namespace * adds back iselfserialize * refactors consts&flags * renames everything to data(field/definition) * adds afterserialization * help * dataclassgen * fuggen help me mannen * Fix most errors on content * Fix engine errors except map loader * maploader & misc fix * misc fixes * thing * help * refactors datanodes * help me mannen * Separate ITypeSerializer into reader and writer * Convert all type serializers * priority * adds alot * il fixes * adds robustgen * argh * adds array & enum serialization * fixes dataclasses * adds vec2i / misc fixes * fixes inheritance * a very notcursed todo * fixes some custom dataclasses * push dis * Remove data classes * boutta box * yes * Add angle and regex serializer tests * Make TypeSerializerTest abstract * sets up ioc etc * remove pushinheritance * fixes * Merge fixes, fix yaml hot reloading * General fixes2 * Make enum serialization ignore case * Fix the tag not being copied in data nodes * Fix not properly serializing flag enums * Fix component serialization on startup * Implement ValueDataNode ToString * Serialization IL fixes, fix return and string equality * Remove async from prototype manager * Make serializing unsupported node as enum exception more descriptive * Fix serv3 tryread casting to serializer instead of reader * Add constructor for invalid node type exception * Temporary fix for SERV3: Turn populate delegate into regular code * Fix not copying the data of non primitive types * Fix not using the data definition found in copying * Make ISerializationHooks require explicit implementations * Add test for serialization inheritance * Improve IsOverridenIn method * Fix error message when a data definition is null * Add method to cast a read value in Serv3Manager * Rename IServ3Manager to ISerializationManager * Rename usages of serv3manager, add generic copy method * Fix IL copy method lookup * Rename old usages of serv3manager * Add ITypeCopier * resistance is futile * we will conquer this codebase * Add copy method to all serializers * Make primitive mismatch error message more descriptive * bing bong im going to freacking heck * oopsie moment * hello are you interested in my wares * does generic serializers under new architecture * Convert every non generic serializer to the new format, general fixes * Update usgaes of generic serializers, cleanup * does some pushinheritance logic * finishes pushinheritance FRAMEWORK * shed * Add box2, color and component registry serializer tests * Create more deserialized types and store prototypes with their deserialized results * Fixes and serializer updates * Add serialization manager extensions * adds pushinheritance * Update all prototypes to have a parent and have consistent id/parent properties * Fix grammar component serialization * Add generic serializer tests * thonk * Add array serializer test * Replace logger warning calls with exceptions * fixes * Move redundant methods to serialization manager extensions, cleanup * Add array serialization * fixes context * more fixes * argh * inheritance * this should do it * fixes * adds copiers & fixes some stuff * copiers use context v1 * finishing copy context * more context fixes * Test fixes * funky maps * Fix server user interface component serialization * Fix value tuple serialization * Add copying for value types and arrays. Fix copy internal for primitives, enums and strings * fixes * fixes more stuff * yes * Make abstract/interface skips debugs instead of warnings * Fix typo * Make some dictionaries readonly * Add checks for the serialization manager initializing and already being initialized * Add base type required and usage for MeansDataDefinition and ImplicitDataDefinitionForInheritorsAttribute * copy by ref * Fix exception wording * Update data field required summary with the new forbidden docs * Use extension in map loader * wanna erp * Change serializing to not use il temporarily * Make writing work with nullable types * pushing * check * cuddling slaps HARD * Add serialization priority test * important fix * a serialization thing * serializer moment * Add validation for some type serializers * adds context * moar context * fixes * Do the thing for appearance * yoo lmao * push haha pp * Temporarily make copy delegate regular c# code * Create deserialized component registry to handle not inheriting conflicting references * YAML LINTER BABY * ayes * Fix sprite component norot not being default true like in latest master * Remove redundant todos * Add summary doc to every ISerializationManager method * icon fixes * Add skip hook argument to readers and copiers * Merge fixes * Fix ordering of arguments in read and copy reflection call * Fix user interface components deserialization * pew pew * i am going to HECK * Add MustUseReturnValue to copy-over methods * Make serialization log calls use the same sawmill * gamin * Fix doc errors in ISerializationManager.cs * goodbye brave soldier * fixes * WIP merge fixes and entity serialization * aaaaaaaaaaaaaaa * aaaaaaaaaaaaaaa * adds inheritancebehaviour * test/datafield fixes * forgot that one * adds more verbose validation * This fixes the YAML hot reloading * Replace yield break with Enumerable.Empty * adds copiers * aaaaaaaaaaaaa * array fix priority fix misc fixes * fix(?) * fix. * funny map serialization (wip) * funny map serialization (wip) * Add TODO * adds proper info the validation * Make yaml linter 5 times faster (~80% less execution time) * Improves the error message for missing fields in the linter * Include component name in unknown component type error node * adds alwaysrelevant usa * fixes mapsaving * moved surpressor to analyzers proj * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 2ee4cc2. * Add serialization to RobustServerSimulation and mock reflection methods Fixes container tests * Fix nullability warnings * Improve yaml linter message feedback * oops moment * Add IEquatable, IComparable, ToString and operators to DataPosition Rename it to NodeMark Make it a readonly struct * Remove try catch from enum parsing * Make dependency management in serialization less bad * Make dependencies an argument instead of a property on the serialization manager * Clean up type serializers * Improve validation messages and resourc epath checking * Fix sprite error message * reached perfection Co-authored-by: Paul <[email protected]> Co-authored-by: DrSmugleaf <[email protected]> Co-authored-by: Vera Aguilera Puerto <[email protected]>
1 parent 93018c9 commit 80f9f24

File tree

202 files changed

+8582
-5313
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

202 files changed

+8582
-5313
lines changed

Robust.Analyzers/Diagnostics.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Microsoft.CodeAnalysis;
2+
3+
namespace Robust.Generators
4+
{
5+
public static class Diagnostics
6+
{
7+
public static SuppressionDescriptor MeansImplicitAssignment =>
8+
new SuppressionDescriptor("RADC1000", "CS0649", "Marked as implicitly assigned.");
9+
}
10+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using System.Collections.Immutable;
3+
using System.Linq;
4+
using Microsoft.CodeAnalysis;
5+
using Microsoft.CodeAnalysis.Diagnostics;
6+
using Robust.Generators;
7+
8+
namespace Robust.Analyzers
9+
{
10+
[DiagnosticAnalyzer(LanguageNames.CSharp)]
11+
public class MeansImplicitAssigmentSuppressor : DiagnosticSuppressor
12+
{
13+
const string MeansImplicitAssignmentAttribute = "Robust.Shared.MeansImplicitAssignmentAttribute";
14+
15+
public override void ReportSuppressions(SuppressionAnalysisContext context)
16+
{
17+
var implAttr = context.Compilation.GetTypeByMetadataName(MeansImplicitAssignmentAttribute);
18+
foreach (var reportedDiagnostic in context.ReportedDiagnostics)
19+
{
20+
if(reportedDiagnostic.Id != Diagnostics.MeansImplicitAssignment.SuppressedDiagnosticId) continue;
21+
22+
var node = reportedDiagnostic.Location.SourceTree?.GetRoot(context.CancellationToken).FindNode(reportedDiagnostic.Location.SourceSpan);
23+
if (node == null) continue;
24+
25+
var symbol = context.GetSemanticModel(reportedDiagnostic.Location.SourceTree).GetDeclaredSymbol(node);
26+
27+
if (symbol == null || !symbol.GetAttributes().Any(a =>
28+
a.AttributeClass?.GetAttributes().Any(attr =>
29+
SymbolEqualityComparer.Default.Equals(attr.AttributeClass, implAttr)) == true))
30+
{
31+
continue;
32+
}
33+
34+
context.ReportSuppression(Suppression.Create(
35+
Diagnostics.MeansImplicitAssignment,
36+
reportedDiagnostic));
37+
}
38+
}
39+
40+
public override ImmutableArray<SuppressionDescriptor> SupportedSuppressions => ImmutableArray.Create(Diagnostics.MeansImplicitAssignment);
41+
}
42+
}

Robust.Client/Animations/Animation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Robust.Client.Animations
1313
/// <seealso cref="AnimationPlayerComponent"/>
1414
public sealed class Animation
1515
{
16-
public readonly List<AnimationTrack> AnimationTracks = new();
16+
public List<AnimationTrack> AnimationTracks { get; private set; } = new();
1717

1818
public TimeSpan Length { get; set; }
1919
}

Robust.Client/Animations/AnimationTrackPlaySound.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public sealed class AnimationTrackPlaySound : AnimationTrack
1515
/// <summary>
1616
/// A list of key frames for when to fire flicks.
1717
/// </summary>
18-
public readonly List<KeyFrame> KeyFrames = new();
18+
public List<KeyFrame> KeyFrames { get; private set; } = new();
1919

2020
public override (int KeyFrameIndex, float FramePlayingTime) InitPlayback()
2121
{

Robust.Client/Animations/AnimationTrackProperty.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Robust.Client.Animations
1010
/// </summary>
1111
public abstract class AnimationTrackProperty : AnimationTrack
1212
{
13-
public readonly List<KeyFrame> KeyFrames = new();
13+
public List<KeyFrame> KeyFrames { get; protected set; } = new();
1414

1515
/// <summary>
1616
/// How to interpolate values when between two keyframes.

Robust.Client/Animations/AnimationTrackSpriteFlick.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public sealed class AnimationTrackSpriteFlick : AnimationTrack
1515
/// <summary>
1616
/// A list of key frames for when to fire flicks.
1717
/// </summary>
18-
public readonly List<KeyFrame> KeyFrames = new();
18+
public List<KeyFrame> KeyFrames { get; private set; } = new();
1919

2020
// TODO: Should this layer key be per keyframe maybe?
2121
/// <summary>

Robust.Client/ClientIoC.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
using Robust.Shared.Players;
2828
using Robust.Shared.Prototypes;
2929
using Robust.Shared.Reflection;
30+
using Robust.Shared.Serialization;
31+
using Robust.Shared.Serialization.Manager;
3032

3133
namespace Robust.Client
3234
{
@@ -101,7 +103,6 @@ public static void RegisterIoC(GameController.DisplayMode mode)
101103
IoCManager.Register<IViewVariablesManagerInternal, ViewVariablesManager>();
102104
IoCManager.Register<IClientConGroupController, ClientConGroupController>();
103105
IoCManager.Register<IScriptClient, ScriptClient>();
104-
//IoCManager.Register<IXamlCompiler, XamlCompiler>();
105106
}
106107
}
107108
}

Robust.Client/Console/Commands/Debug.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
using Robust.Client.Debugging;
1313
using Robust.Client.Graphics;
1414
using Robust.Client.ResourceManagement;
15-
using Robust.Client.ResourceManagement.ResourceTypes;
1615
using Robust.Client.UserInterface;
1716
using Robust.Client.UserInterface.Controls;
1817
using Robust.Client.UserInterface.CustomControls;

Robust.Client/GameController.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.IO;
33
using System.Net;
44
using System.Threading.Tasks;
@@ -27,6 +27,7 @@
2727
using Robust.Shared.Network;
2828
using Robust.Shared.Prototypes;
2929
using Robust.Shared.Serialization;
30+
using Robust.Shared.Serialization.Manager;
3031
using Robust.Shared.Timing;
3132
using Robust.Shared.Utility;
3233

@@ -44,7 +45,7 @@ internal sealed partial class GameController : IGameControllerInternal
4445
[Dependency] private readonly IUserInterfaceManagerInternal _userInterfaceManager = default!;
4546
[Dependency] private readonly IBaseClient _client = default!;
4647
[Dependency] private readonly IInputManager _inputManager = default!;
47-
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
48+
[Dependency] private readonly IClientConsoleHost _console = default!;
4849
[Dependency] private readonly ITimerManager _timerManager = default!;
4950
[Dependency] private readonly IClientEntityManager _entityManager = default!;
5051
[Dependency] private readonly IPlacementManager _placementManager = default!;
@@ -154,6 +155,8 @@ public bool Startup(Func<ILogHandler>? logHandlerFactory = null)
154155
_configurationManager.LoadCVarsFromAssembly(loadedModule);
155156
}
156157

158+
IoCManager.Resolve<ISerializationManager>().Initialize();
159+
157160
// Call Init in game assemblies.
158161
_modLoader.BroadcastRunLevel(ModRunLevel.PreInit);
159162
_modLoader.BroadcastRunLevel(ModRunLevel.Init);
@@ -163,7 +166,7 @@ public bool Startup(Func<ILogHandler>? logHandlerFactory = null)
163166
IoCManager.Resolve<INetConfigurationManager>().SetupNetworking();
164167
_serializer.Initialize();
165168
_inputManager.Initialize();
166-
_consoleHost.Initialize();
169+
_console.Initialize();
167170
_prototypeManager.Initialize();
168171
_prototypeManager.LoadDirectory(new ResourcePath(@"/Prototypes/"));
169172
_prototypeManager.Resync();

Robust.Client/GameController/GameController.IoC.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ private static void InitIoC(DisplayMode mode)
1717
RegisterReflection();
1818
}
1919

20-
2120
internal static void RegisterReflection()
2221
{
2322
// Gets a handle to the shared and the current (client) dll.

Robust.Client/GameObjects/ClientComponentFactory.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public ClientComponentFactory()
5454

5555
#if DEBUG
5656
Register<DebugExceptionOnAddComponent>();
57-
Register<DebugExceptionExposeDataComponent>();
5857
Register<DebugExceptionInitializeComponent>();
5958
Register<DebugExceptionStartupComponent>();
6059
#endif

Robust.Client/GameObjects/Components/Appearance/AppearanceComponent.cs

Lines changed: 4 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
using Robust.Shared.GameObjects;
55
using Robust.Shared.IoC;
66
using Robust.Shared.Reflection;
7-
using Robust.Shared.Serialization;
8-
using Robust.Shared.Utility;
7+
using Robust.Shared.Serialization.Manager.Attributes;
98
using Robust.Shared.ViewVariables;
109
using YamlDotNet.RepresentationModel;
1110

@@ -15,13 +14,11 @@ public sealed class AppearanceComponent : SharedAppearanceComponent
1514
{
1615
[ViewVariables]
1716
private Dictionary<object, object> data = new();
17+
1818
[ViewVariables]
19+
[DataField("visuals")]
1920
internal List<AppearanceVisualizer> Visualizers = new();
2021

21-
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
22-
23-
private static bool _didRegisterSerializer;
24-
2522
[ViewVariables]
2623
private bool _appearanceDirty;
2724

@@ -107,18 +104,6 @@ internal void UnmarkDirty()
107104
_appearanceDirty = false;
108105
}
109106

110-
public override void ExposeData(ObjectSerializer serializer)
111-
{
112-
if (!_didRegisterSerializer)
113-
{
114-
YamlObjectSerializer.RegisterTypeSerializer(typeof(AppearanceVisualizer),
115-
new VisualizerTypeSerializer(_reflectionManager));
116-
_didRegisterSerializer = true;
117-
}
118-
119-
serializer.DataFieldCached(ref Visualizers, "visuals", new List<AppearanceVisualizer>());
120-
}
121-
122107
public override void Initialize()
123108
{
124109
base.Initialize();
@@ -131,78 +116,6 @@ public override void Initialize()
131116
MarkDirty();
132117
}
133118

134-
class VisualizerTypeSerializer : YamlObjectSerializer.TypeSerializer
135-
{
136-
private readonly IReflectionManager _reflectionManager;
137-
138-
public VisualizerTypeSerializer(IReflectionManager reflectionManager)
139-
{
140-
_reflectionManager = reflectionManager;
141-
}
142-
143-
public override object NodeToType(Type type, YamlNode node, YamlObjectSerializer serializer)
144-
{
145-
var mapping = (YamlMappingNode) node;
146-
var nodeType = mapping.GetNode("type");
147-
switch (nodeType.AsString())
148-
{
149-
case SpriteLayerToggle.NAME:
150-
var keyString = mapping.GetNode("key").AsString();
151-
object key;
152-
if (_reflectionManager.TryParseEnumReference(keyString, out var @enum))
153-
{
154-
key = @enum;
155-
}
156-
else
157-
{
158-
key = keyString;
159-
}
160-
161-
var layer = mapping.GetNode("layer").AsInt();
162-
return new SpriteLayerToggle(key, layer);
163-
164-
default:
165-
var visType = _reflectionManager.LooseGetType(nodeType.AsString());
166-
if (!typeof(AppearanceVisualizer).IsAssignableFrom(visType))
167-
{
168-
throw new InvalidOperationException();
169-
}
170-
171-
var vis = (AppearanceVisualizer) Activator.CreateInstance(visType)!;
172-
vis.LoadData(mapping);
173-
return vis;
174-
}
175-
}
176-
177-
public override YamlNode TypeToNode(object obj, YamlObjectSerializer serializer)
178-
{
179-
switch (obj)
180-
{
181-
case SpriteLayerToggle spriteLayerToggle:
182-
YamlScalarNode key;
183-
if (spriteLayerToggle.Key is Enum)
184-
{
185-
var name = spriteLayerToggle.Key.GetType().FullName;
186-
key = new YamlScalarNode($"{name}.{spriteLayerToggle.Key}");
187-
}
188-
else
189-
{
190-
key = new YamlScalarNode(spriteLayerToggle.Key.ToString());
191-
}
192-
193-
return new YamlMappingNode
194-
{
195-
{new YamlScalarNode("type"), new YamlScalarNode(SpriteLayerToggle.NAME)},
196-
{new YamlScalarNode("key"), key},
197-
{new YamlScalarNode("layer"), new YamlScalarNode(spriteLayerToggle.SpriteLayer.ToString())},
198-
};
199-
default:
200-
// TODO: A proper way to do serialization here.
201-
// I can't use the ExposeData system here since that's specific to entity serializers.
202-
return new YamlMappingNode();
203-
}
204-
}
205-
}
206119

207120
internal class SpriteLayerToggle : AppearanceVisualizer
208121
{
@@ -223,15 +136,9 @@ public SpriteLayerToggle(object key, int spriteLayer)
223136
/// Handles the visualization of data inside of an appearance component.
224137
/// Implementations of this class are NOT bound to a specific entity, they are flyweighted across multiple.
225138
/// </summary>
139+
[ImplicitDataDefinitionForInheritors]
226140
public abstract class AppearanceVisualizer
227141
{
228-
/// <summary>
229-
/// Load data from the prototype declaring this visualizer, to configure settings and such.
230-
/// </summary>
231-
public virtual void LoadData(YamlMappingNode node)
232-
{
233-
}
234-
235142
/// <summary>
236143
/// Initializes an entity to be managed by this appearance controller.
237144
/// DO NOT assume this is your only entity. Visualizers are shared.

Robust.Client/GameObjects/Components/Eye/EyeComponent.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
using Robust.Shared.IoC;
44
using Robust.Shared.Map;
55
using Robust.Shared.Maths;
6+
using Robust.Shared.Prototypes;
67
using Robust.Shared.Serialization;
8+
using Robust.Shared.Serialization.Manager.Attributes;
79
using Robust.Shared.ViewVariables;
810

911
namespace Robust.Client.GameObjects
@@ -20,7 +22,9 @@ public class EyeComponent : SharedEyeComponent
2022

2123
// Horrible hack to get around ordering issues.
2224
private bool _setCurrentOnInitialize;
23-
private bool _setDrawFovOnInitialize;
25+
[DataField("drawFov")]
26+
private bool _setDrawFovOnInitialize = true;
27+
[DataField("zoom")]
2428
private Vector2 _setZoomOnInitialize = Vector2.One/2f;
2529
private Vector2 _offset = Vector2.Zero;
2630

@@ -157,15 +161,6 @@ public override void OnRemove()
157161
Current = false;
158162
}
159163

160-
/// <inheritdoc />
161-
public override void ExposeData(ObjectSerializer serializer)
162-
{
163-
base.ExposeData(serializer);
164-
165-
serializer.DataFieldCached(ref _setZoomOnInitialize, "zoom", Vector2.One/2f);
166-
serializer.DataFieldCached(ref _setDrawFovOnInitialize, "drawFov", true);
167-
}
168-
169164
/// <summary>
170165
/// Updates the Eye of this entity with the transform position. This has to be called every frame to
171166
/// keep the view following the entity.

0 commit comments

Comments
 (0)