Keep Eve command emission in runtime package

This commit is contained in:
Meta Vens 2026-06-14 08:25:05 +01:00
commit 512e198389
5 changed files with 23 additions and 75 deletions

Binary file not shown.

View file

@ -9,5 +9,6 @@
<ItemGroup>
<ProjectReference Include="..\Aetheria.State\Aetheria.State.csproj" />
<ProjectReference Include="..\Aetheria.State.Unity\Aetheria.State.Unity.csproj" />
</ItemGroup>
</Project>

View file

@ -2,6 +2,8 @@ using Aetheria.State;
using Aetheria.State.Documents;
using Aetheria.State.Migration;
using GameCult.Caching;
using GameCult.Aetheria.State.Unity;
using GameCult.Eve.Surface;
var root = args.Length > 0 ? args[0] : Directory.GetCurrentDirectory();
var statePath = AetheriaStatePaths.ResolveDefaultStatePath(root);
@ -105,20 +107,24 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s
await node.PutOperationsSurfaceAsync(AetheriaOperationsSurfaceProjector.Build(drainStatus));
await node.PutProviderAdvertisementAsync(AetheriaProviderAdvertisementProjector.Build(statePath, now));
AetheriaEveCommandBridge.QueueCommand(
AetheriaRuntimeEveCommandLog.QueueCommand(
statePath,
AetheriaProviderAdvertisementProjector.ProviderId,
AetheriaCatalogSurfaceProjector.SurfaceId,
"aetheria.catalog.refresh",
new Dictionary<string, string> { ["source"] = "state-smoke" },
"aetheria-state-smoke");
AetheriaEveCommandBridge.QueueCommand(
new EveSurfaceCommandRequest(
AetheriaProviderAdvertisementProjector.ProviderId,
AetheriaCatalogSurfaceProjector.SurfaceId,
"aetheria.catalog.refresh",
new Dictionary<string, string> { ["source"] = "state-smoke" },
DateTimeOffset.UtcNow,
"aetheria-state-smoke"));
AetheriaRuntimeEveCommandLog.QueueCommand(
statePath,
AetheriaProviderAdvertisementProjector.ProviderId,
AetheriaCatalogSurfaceProjector.SurfaceId,
"aetheria.catalog.unknown",
new Dictionary<string, string> { ["source"] = "state-smoke" },
"aetheria-state-smoke");
new EveSurfaceCommandRequest(
AetheriaProviderAdvertisementProjector.ProviderId,
AetheriaCatalogSurfaceProjector.SurfaceId,
"aetheria.catalog.unknown",
new Dictionary<string, string> { ["source"] = "state-smoke" },
DateTimeOffset.UtcNow,
"aetheria-state-smoke"));
var eveCommandReport = await AetheriaEveCommandBridge.ApplyPendingAsync(node);
var eveCommandStatus = new AetheriaEveCommandDrainStatus
{

View file

@ -1,4 +1,3 @@
using System.Buffers;
using Aetheria.State.Documents;
using MessagePack;
@ -80,43 +79,6 @@ public static class AetheriaEveCommandBridge
return report;
}
public static void QueueCommand(
string stateFilePath,
string providerId,
string surfaceId,
string command,
IReadOnlyDictionary<string, string>? payload = null,
string clientId = "aetheria-state")
{
var issuedAtUtc = DateTimeOffset.UtcNow.UtcDateTime.ToString("O");
var commandId = Guid.NewGuid().ToString("N");
var pendingDirectory = GetPendingDirectory(stateFilePath);
Directory.CreateDirectory(pendingDirectory);
var finalPath = Path.Combine(
pendingDirectory,
$"{issuedAtUtc.Replace(':', '-')}.{StableToken(surfaceId)}.{StableToken(command)}.{commandId}.cc");
var tempPath = finalPath + ".tmp";
var buffer = new ArrayBufferWriter<byte>();
var writer = new MessagePackWriter(buffer);
writer.WriteArrayHeader(8);
writer.Write(CommandSchema);
writer.Write(commandId);
writer.Write(providerId ?? "");
writer.Write(surfaceId ?? "");
writer.Write(command ?? "");
writer.Write(issuedAtUtc);
writer.Write(clientId ?? "");
WritePayload(ref writer, payload);
writer.Flush();
File.WriteAllBytes(tempPath, buffer.WrittenSpan.ToArray());
if (File.Exists(finalPath))
File.Delete(finalPath);
File.Move(tempPath, finalPath);
}
private static AetheriaPendingEveCommand ReadCommand(string path)
{
var reader = new MessagePackReader(File.ReadAllBytes(path));
@ -199,17 +161,6 @@ public static class AetheriaEveCommandBridge
};
}
private static void WritePayload(ref MessagePackWriter writer, IReadOnlyDictionary<string, string>? payload)
{
payload ??= new Dictionary<string, string>(0, StringComparer.Ordinal);
writer.WriteMapHeader(payload.Count);
foreach (var entry in payload.OrderBy(entry => entry.Key, StringComparer.Ordinal))
{
writer.Write(entry.Key ?? "");
writer.Write(entry.Value ?? "");
}
}
private static IReadOnlyDictionary<string, string> ReadPayload(ref MessagePackReader reader)
{
var count = reader.ReadMapHeader();
@ -225,20 +176,6 @@ public static class AetheriaEveCommandBridge
return payload;
}
private static string StableToken(string value)
{
if (string.IsNullOrWhiteSpace(value))
return "empty";
var chars = value
.Select(character => char.IsLetterOrDigit(character) ? character : '-')
.ToArray();
var token = new string(chars).Trim('-').ToLowerInvariant();
while (token.Contains("--", StringComparison.Ordinal))
token = token.Replace("--", "-", StringComparison.Ordinal);
return string.IsNullOrWhiteSpace(token) ? "empty" : token;
}
private static string ReadString(ref MessagePackReader reader)
{
return reader.ReadString() ?? "";

View file

@ -900,6 +900,10 @@ First Aetheria surfaces to publish:
validates provider/surface/command templates, invokes the current refresh
handlers, republishes accepted surfaces, rejects unknown commands, and
records typed command-drain status.
- Done: delete provider-side Eve command emission from
`AetheriaEveCommandBridge`; renderer/runtime command files are queued
through `AetheriaRuntimeEveCommandLog`, while the provider bridge only
validates, applies, reports, and deletes accounted commands.
- Extend the command bridge beyond refresh commands as gameplay/editor Eve
surfaces acquire provider-owned handlers.
- Wire the presenter into a Unity scene/prefab for the first runtime surface