Restore entity identity semantics in SoA v2
This commit is contained in:
parent
03407c3165
commit
a6f00c6ac0
4 changed files with 78 additions and 7 deletions
|
|
@ -26,6 +26,7 @@ namespace GameCult.Eve.Surface
|
|||
[Key(11)] public EveEntitySoaDirtyRange[] DirtyRanges { get; set; } = Array.Empty<EveEntitySoaDirtyRange>();
|
||||
[Key(12)] public EveEntityRenderGroup[] RenderGroups { get; set; } = Array.Empty<EveEntityRenderGroup>();
|
||||
[Key(13)] public EveEntityIdentity[] Identities { get; set; } = Array.Empty<EveEntityIdentity>();
|
||||
[Key(14)] public long FrameId { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
|
|
@ -65,6 +66,11 @@ namespace GameCult.Eve.Surface
|
|||
[Key(0)] public int Index { get; set; }
|
||||
[Key(1)] public string EntityId { get; set; } = "";
|
||||
[Key(2)] public string EntityKind { get; set; } = "";
|
||||
[Key(3)] public string Label { get; set; } = "";
|
||||
[Key(4)] public string Faction { get; set; } = "";
|
||||
[Key(5)] public bool Selectable { get; set; }
|
||||
[Key(6)] public bool Controllable { get; set; }
|
||||
[Key(7)] public string AssetRef { get; set; } = "";
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
|
|
|
|||
|
|
@ -40,22 +40,24 @@ namespace GameCult.Eve.UnityScene
|
|||
var identity = document.Identities.FirstOrDefault(item => item.Index == entityIndex);
|
||||
var entityId = identity?.EntityId ?? $"entity:{entityIndex}";
|
||||
next.Add(entityId);
|
||||
var assetRef = renderGroup?.MeshAssetRef ?? "";
|
||||
var assetRef = string.IsNullOrWhiteSpace(identity?.AssetRef)
|
||||
? renderGroup?.MeshAssetRef ?? ""
|
||||
: identity!.AssetRef;
|
||||
_sink.UpsertEntity(
|
||||
new EveUnityPlayableWorldEntity(
|
||||
entityId,
|
||||
entityId,
|
||||
identity?.EntityKind ?? "entity",
|
||||
entityId,
|
||||
"",
|
||||
string.IsNullOrWhiteSpace(identity?.Label) ? entityId : identity!.Label,
|
||||
identity?.Faction ?? "",
|
||||
assetRef,
|
||||
position.x,
|
||||
position.y,
|
||||
position.z,
|
||||
rotationRadians * 57.2957795f,
|
||||
scale > 0f ? scale : renderGroup?.DefaultScale ?? 1f,
|
||||
selectable: true,
|
||||
controllable: false,
|
||||
selectable: identity?.Selectable ?? true,
|
||||
controllable: identity?.Controllable ?? false,
|
||||
focusCommand: "",
|
||||
moveCommand: "",
|
||||
targetCommand: "",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using GameCult.Eve.Surface;
|
||||
using GameCult.Mesh;
|
||||
using NUnit.Framework;
|
||||
|
|
@ -66,6 +67,33 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
document, new FakeBodyReadLease(descriptor, new byte[4])));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EntitySoaPresenterPreservesProviderAuthoredIdentityFacts()
|
||||
{
|
||||
var bytes = new byte[16];
|
||||
Buffer.BlockCopy(new[] { 12 }, 0, bytes, 0, 4);
|
||||
Buffer.BlockCopy(new[] { 1f, 2f, 3f }, 0, bytes, 4, 12);
|
||||
var document = EntityLeaseDocument();
|
||||
document.Buffers[0].ByteLength = bytes.Length;
|
||||
document.Columns = new[]
|
||||
{
|
||||
new EveEntitySoaColumn { ColumnId = "entity-index", Semantic = "entity.index", BufferId = "hot", ScalarType = "int32", ElementStride = 4, ElementCount = 1 },
|
||||
new EveEntitySoaColumn { ColumnId = "position", Semantic = "transform.position", BufferId = "hot", ScalarType = "float3", ByteOffset = 4, ElementStride = 12, ElementCount = 1 }
|
||||
};
|
||||
var sink = new FakePlayableWorldSceneSink();
|
||||
|
||||
new EveUnityEntitySoaPresenter(sink).Apply(document, new FakeBodyReadLease(document, bytes));
|
||||
|
||||
var entity = sink.Upserts.Single().entity;
|
||||
Assert.That(entity.EntityId, Is.EqualTo("entity:pilot"));
|
||||
Assert.That(entity.Label, Is.EqualTo("Pilot"));
|
||||
Assert.That(entity.EntityKind, Is.EqualTo("player"));
|
||||
Assert.That(entity.Faction, Is.EqualTo("alliance"));
|
||||
Assert.That(entity.Selectable, Is.True);
|
||||
Assert.That(entity.Controllable, Is.True);
|
||||
Assert.That(entity.AssetRef, Is.EqualTo("cultmesh://assets/pilot"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LowerCarriesProviderAdvertisedWorldBoundary()
|
||||
{
|
||||
|
|
@ -1771,6 +1799,20 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
Sequence = 7,
|
||||
Capacity = 1,
|
||||
Buffers = new[] { new EveEntitySoaBuffer { BufferId = "hot", ByteLength = 4 } },
|
||||
Identities = new[]
|
||||
{
|
||||
new EveEntityIdentity
|
||||
{
|
||||
Index = 12,
|
||||
EntityId = "entity:pilot",
|
||||
EntityKind = "player",
|
||||
Label = "Pilot",
|
||||
Faction = "alliance",
|
||||
Selectable = true,
|
||||
Controllable = true,
|
||||
AssetRef = "cultmesh://assets/pilot"
|
||||
}
|
||||
},
|
||||
Columns = new[]
|
||||
{
|
||||
new EveEntitySoaColumn
|
||||
|
|
|
|||
|
|
@ -21,16 +21,37 @@ public sealed class EveSurfaceSerializationCompatibilityTests
|
|||
ProducerEpoch = 3,
|
||||
Sequence = 4,
|
||||
Capacity = 8,
|
||||
Buffers = new[] { new EveEntitySoaBuffer { BufferId = "entity-hot", ByteLength = 64 } }
|
||||
FrameId = 91,
|
||||
Buffers = new[] { new EveEntitySoaBuffer { BufferId = "entity-hot", ByteLength = 64 } },
|
||||
Identities = new[]
|
||||
{
|
||||
new EveEntityIdentity
|
||||
{
|
||||
Index = 0,
|
||||
EntityId = "player",
|
||||
EntityKind = "ship",
|
||||
Label = "Vanguard",
|
||||
Faction = "alliance",
|
||||
Selectable = true,
|
||||
Controllable = true,
|
||||
AssetRef = "cultmesh://assets/player"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var bytes = MessagePackSerializer.Serialize(document, Options);
|
||||
var reader = new MessagePackReader(bytes);
|
||||
var restored = MessagePackSerializer.Deserialize<EveEntitySoaViewDocument>(bytes, Options);
|
||||
|
||||
Assert.That(reader.ReadArrayHeader(), Is.EqualTo(14));
|
||||
Assert.That(reader.ReadArrayHeader(), Is.EqualTo(15));
|
||||
Assert.That(restored.Schema, Is.EqualTo(EveEntitySoaViewDocument.SchemaId));
|
||||
Assert.That(restored.Buffers[0].BufferId, Is.EqualTo("entity-hot"));
|
||||
Assert.That(restored.FrameId, Is.EqualTo(91));
|
||||
Assert.That(restored.Identities[0].Label, Is.EqualTo("Vanguard"));
|
||||
Assert.That(restored.Identities[0].Faction, Is.EqualTo("alliance"));
|
||||
Assert.That(restored.Identities[0].Selectable, Is.True);
|
||||
Assert.That(restored.Identities[0].Controllable, Is.True);
|
||||
Assert.That(restored.Identities[0].AssetRef, Is.EqualTo("cultmesh://assets/player"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
|||
Reference in a new issue