Skip to content

Commit 2fe292b

Browse files
lollekoscomitch
authored andcommitted
Cache (De)SerializeOptions in hot paths (#3547)
They are essentially compile time constants, so we shouldn't allocate them
1 parent b541886 commit 2fe292b

6 files changed

Lines changed: 24 additions & 30 deletions

File tree

engine/Sandbox.Engine/Scene/GameObject/GameObject.Network.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,12 +437,14 @@ internal GameObject FindNetworkRoot()
437437
return Parent.FindNetworkRoot();
438438
}
439439

440+
private static readonly DeserializeOptions _networkRefreshDeserializeOptions = new() { IsRefreshing = true, IsNetworkRefresh = true };
441+
440442
/// <summary>
441443
/// Update hierarchy from a network refresh.
442444
/// </summary>
443445
internal void NetworkRefresh( JsonObject jso )
444446
{
445-
Deserialize( jso, new DeserializeOptions { IsRefreshing = true, IsNetworkRefresh = true } );
447+
Deserialize( jso, _networkRefreshDeserializeOptions );
446448
}
447449

448450
/// <summary>

engine/Sandbox.Engine/Scene/GameObject/GameObject.PrefabInstanceData.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,15 @@ public void InitPatch( Json.Patch patch )
102102
_patch = patch;
103103
}
104104

105+
private static readonly SerializeOptions _serializeOptions = new();
106+
105107
/// <summary>
106108
/// Updates the cached patch that represents differences between this instance and its source prefab.
107109
/// </summary>
108110
public void RefreshPatch()
109111
{
110-
SerializeOptions options = new SerializeOptions();
111112

112-
var instanceData = _instanceRoot.SerializeStandard( options );
113+
var instanceData = _instanceRoot.SerializeStandard( _serializeOptions );
113114

114115
RemapInstanceIdsToPrefabIds( ref instanceData );
115116

engine/Sandbox.Engine/Scene/GameObject/GameObject.Serialize.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ internal bool ShouldSave( GameObject gameObject )
8282
}
8383
}
8484

85+
private static readonly SerializeOptions _defaultSerializeOptions = new();
86+
8587
public struct DeserializeOptions
8688
{
8789
/// <summary>
@@ -111,13 +113,15 @@ public struct DeserializeOptions
111113
public Transform? TransformOverride { get; set; }
112114
}
113115

116+
private static readonly DeserializeOptions _defaultDeserializeOptions = new();
117+
114118
/// <summary>
115119
/// Returns either a full JsonObject with all the GameObjects data,
116120
/// or if this GameObject is a prefab instance, it will return an object containing the patch/diff between instance and prefab.
117121
/// </summary>
118122
public virtual JsonObject Serialize( SerializeOptions options = null )
119123
{
120-
options ??= new SerializeOptions();
124+
options ??= _defaultSerializeOptions;
121125

122126
if ( !options.ShouldSave( this ) ) return null;
123127

@@ -302,8 +306,7 @@ internal virtual JsonObject SerializeStandard( SerializeOptions options )
302306
return json;
303307
}
304308

305-
306-
public virtual void Deserialize( JsonObject node ) => Deserialize( node, new DeserializeOptions() );
309+
public virtual void Deserialize( JsonObject node ) => Deserialize( node, _defaultDeserializeOptions );
307310

308311
public virtual void Deserialize( JsonObject node, DeserializeOptions options )
309312
{

engine/Sandbox.Engine/Scene/Networking/NetworkObject.cs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ internal void SendNetworkDestroy()
231231
SceneNetworkSystem.Instance.Broadcast( msg );
232232
}
233233

234+
private static readonly GameObject.SerializeOptions _refreshSerializeOptions = new() { SingleNetworkObject = true };
235+
234236
internal ObjectRefreshMsg GetRefreshMessage()
235237
{
236238
var system = SceneNetworkSystem.Instance;
@@ -239,23 +241,20 @@ internal ObjectRefreshMsg GetRefreshMessage()
239241

240242
var snapshot = ((IDeltaSnapshot)this).WriteSnapshotState();
241243

242-
var o = new GameObject.SerializeOptions
243-
{
244-
SingleNetworkObject = true
245-
};
246-
247244
var msg = new ObjectRefreshMsg
248245
{
249246
Guid = GameObject.Id,
250247
Parent = GameObject.Parent.Id,
251-
JsonData = GameObject.Serialize( o ).ToJsonString(),
248+
JsonData = GameObject.Serialize( _refreshSerializeOptions ).ToJsonString(),
252249
TableData = WriteReliableData(),
253250
Snapshot = system.DeltaSnapshots.GetFullSnapshotData( snapshot )
254251
};
255252

256253
return msg;
257254
}
258255

256+
private static readonly GameObject.SerializeOptions _refreshDescendantSerializeOptions = new() { IgnoreChildren = true };
257+
259258
internal void SendNetworkRefresh( GameObject go )
260259
{
261260
var system = SceneNetworkSystem.Instance;
@@ -288,17 +287,11 @@ internal void SendNetworkRefresh( GameObject go )
288287
{
289288
var snapshot = ((IDeltaSnapshot)this).WriteSnapshotState();
290289

291-
// Only this one object...
292-
var options = new GameObject.SerializeOptions
293-
{
294-
IgnoreChildren = true
295-
};
296-
297290
var msg = new ObjectRefreshDescendantMsg
298291
{
299292
GameObjectId = GameObject.Id,
300293
ParentId = go.Parent.Id,
301-
JsonData = go.Serialize( options ).ToJsonString(),
294+
JsonData = go.Serialize( _refreshDescendantSerializeOptions ).ToJsonString(),
302295
TableData = WriteReliableData(),
303296
Snapshot = system.DeltaSnapshots.GetFullSnapshotData( snapshot )
304297
};
@@ -579,16 +572,16 @@ internal void TransmitStateChanged()
579572
LocalSnapshotState.ClearConnections();
580573
}
581574

575+
private static readonly GameObject.SerializeOptions _createSerializeOptions = new() { SingleNetworkObject = true };
576+
582577
internal ObjectCreateMsg GetCreateMessage()
583578
{
584-
var o = new GameObject.SerializeOptions { SingleNetworkObject = true };
585-
586579
if ( GameObject.Parent is null )
587580
{
588581
throw new( $"GameObject {GameObject.Id} ({GameObject.Name} has invalid parent" );
589582
}
590583

591-
var jsonData = GameObject.Serialize( o );
584+
var jsonData = GameObject.Serialize( _createSerializeOptions );
592585
if ( jsonData is null )
593586
{
594587
throw new( $"Unable to serialize {GameObject.Id} ({GameObject.Name})" );

engine/Sandbox.Engine/Scene/Networking/SceneNetworkSystem.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ public override async Task MountVPKs( Connection source, MountedVPKsResponse msg
281281
MountedVPKs = await MountMaps( msg.MountedVPKs );
282282
}
283283

284+
private static readonly GameObject.SerializeOptions _snapshotSerializeOptions = new() { SceneForNetwork = true };
285+
284286
/// <summary>
285287
/// A client has joined and wants a snapshot of the world.
286288
/// </summary>
@@ -291,16 +293,11 @@ public override void GetSnapshot( Connection source, ref SnapshotMsg msg )
291293

292294
msg.Time = Time.Now;
293295

294-
var o = new GameObject.SerializeOptions
295-
{
296-
SceneForNetwork = true
297-
};
298-
299296
var analytic = new Api.Events.EventRecord( "SceneNetworkSystem.GetSnapshot" );
300297

301298
using ( analytic.ScopeTimer( "SceneTime" ) )
302299
{
303-
msg.SceneData = Game.ActiveScene.Serialize( o ).ToJsonString();
300+
msg.SceneData = Game.ActiveScene.Serialize( _snapshotSerializeOptions ).ToJsonString();
304301
}
305302

306303
using ( analytic.ScopeTimer( "NetworkObjectTime" ) )

engine/Sandbox.Engine/Scene/Scene/Scene.LoadSave.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,6 @@ public override void Deserialize( JsonObject node, DeserializeOptions option )
217217
}
218218
}
219219

220-
public override void Deserialize( JsonObject node ) => Deserialize( node, new DeserializeOptions() );
221-
222220
internal JsonObject SerializeProperties()
223221
{
224222
var jso = new JsonObject();

0 commit comments

Comments
 (0)