Keep Eve command emission in runtime package
This commit is contained in:
parent
19297f2252
commit
512e198389
5 changed files with 23 additions and 75 deletions
Binary file not shown.
|
|
@ -9,5 +9,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Aetheria.State\Aetheria.State.csproj" />
|
||||
<ProjectReference Include="..\Aetheria.State.Unity\Aetheria.State.Unity.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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() ?? "";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue