Implement engine-bridge v2 plugin masquerade (#10)
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
namespace Recordingtest.EngineBridge.Client;
|
||||
|
||||
public sealed class EngineBridgeException : Exception
|
||||
{
|
||||
public string Endpoint { get; }
|
||||
public EngineBridgeException(string endpoint, string message, Exception? inner = null)
|
||||
: base($"engine-bridge {endpoint}: {message}", inner)
|
||||
{
|
||||
Endpoint = endpoint;
|
||||
}
|
||||
}
|
||||
121
src/Recordingtest.EngineBridge.Client/HmEgHttpSnapshot.cs
Normal file
121
src/Recordingtest.EngineBridge.Client/HmEgHttpSnapshot.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Recordingtest.EngineBridge.Client;
|
||||
|
||||
public sealed class HmEgHttpSnapshot : IEngineSnapshot, IDisposable
|
||||
{
|
||||
public const string DefaultBaseUrl = "http://localhost:38080";
|
||||
private readonly HttpClient _http;
|
||||
private readonly bool _ownsClient;
|
||||
private readonly string _baseUrl;
|
||||
|
||||
public HmEgHttpSnapshot(string baseUrl = DefaultBaseUrl, HttpClient? httpClient = null, TimeSpan? timeout = null)
|
||||
{
|
||||
_baseUrl = baseUrl.TrimEnd('/');
|
||||
if (httpClient is null)
|
||||
{
|
||||
_http = new HttpClient { Timeout = timeout ?? TimeSpan.FromSeconds(2) };
|
||||
_ownsClient = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_http = httpClient;
|
||||
if (timeout.HasValue) _http.Timeout = timeout.Value;
|
||||
_ownsClient = false;
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<string> SelectedObjectIds
|
||||
{
|
||||
get
|
||||
{
|
||||
using var doc = Get("/selection");
|
||||
var arr = doc.RootElement.GetProperty("selected_ids");
|
||||
var list = new List<string>(arr.GetArrayLength());
|
||||
foreach (var e in arr.EnumerateArray()) list.Add(e.GetString() ?? string.Empty);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public CameraState Camera
|
||||
{
|
||||
get
|
||||
{
|
||||
using var doc = Get("/camera");
|
||||
var r = doc.RootElement;
|
||||
return new CameraState(
|
||||
ToArray(r.GetProperty("eye")),
|
||||
ToArray(r.GetProperty("target")),
|
||||
ToArray(r.GetProperty("up")),
|
||||
r.GetProperty("fov").GetDouble());
|
||||
}
|
||||
}
|
||||
|
||||
public SceneSummary Scene
|
||||
{
|
||||
get
|
||||
{
|
||||
using var doc = Get("/scene");
|
||||
var r = doc.RootElement;
|
||||
string? path = r.TryGetProperty("document_path", out var dp) && dp.ValueKind == JsonValueKind.String ? dp.GetString() : null;
|
||||
return new SceneSummary(r.GetProperty("object_count").GetInt32(), path);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRenderComplete
|
||||
{
|
||||
get
|
||||
{
|
||||
using var doc = Get("/render");
|
||||
return doc.RootElement.GetProperty("complete").GetBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsHealthy
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
using var doc = Get("/health");
|
||||
return doc.RootElement.TryGetProperty("status", out var s) && s.GetString() == "ok";
|
||||
}
|
||||
catch (EngineBridgeException) { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
private JsonDocument Get(string endpoint)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var resp = _http.GetAsync(_baseUrl + endpoint).GetAwaiter().GetResult();
|
||||
if (!resp.IsSuccessStatusCode)
|
||||
throw new EngineBridgeException(endpoint, $"HTTP {(int)resp.StatusCode}");
|
||||
var body = resp.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||
return JsonDocument.Parse(body);
|
||||
}
|
||||
catch (EngineBridgeException) { throw; }
|
||||
catch (TaskCanceledException ex)
|
||||
{
|
||||
throw new EngineBridgeException(endpoint, "timeout", ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new EngineBridgeException(endpoint, ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static double[] ToArray(JsonElement e)
|
||||
{
|
||||
var arr = new double[e.GetArrayLength()];
|
||||
int i = 0;
|
||||
foreach (var item in e.EnumerateArray()) arr[i++] = item.GetDouble();
|
||||
return arr;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_ownsClient) _http.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<RootNamespace>Recordingtest.EngineBridge.Client</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Recordingtest.EngineBridge\Recordingtest.EngineBridge.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user