Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions bindings/dotnet/src/Gua.Core/GuaSpatialHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ public struct GuaSpatialHostOptions
public uint MaxProviders, MaxOwners, MaxQueueDepth, MaxQueriesPerBatch, MaxHitsPerQuery;
public double QueryDeadlineMs, MaxBatchWorkMs;
}
/// <summary>Conservative binary64 bounds of prepared engine geometry plus the
/// original query. Trusted adapter input; never accept this from a client.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct GuaSpatialEngineBounds
{
internal uint StructSize;
public double MinX, MinY, MinZ, MaxX, MaxY, MaxZ;
}
internal sealed class SpatialHostHandle : SafeHandleZeroOrMinusOneIsInvalid
{
internal SpatialHostHandle(nint p) : base(true) => SetHandle(p);
Expand Down Expand Up @@ -84,6 +92,15 @@ public void Complete(ulong lease, GuaSpatialDocument execution)
using var refs = new SpatialReferences();
Check(Native.gua_spatial_host_complete(_handle, lease, execution.Use(refs), out var e), e);
}
/// <summary>After Take and before physics, check prepared engine bounds
/// against current grants. Retained for subsequent revocation checks.
/// Returns whether the explicit loaded region contains the entire bound.</summary>
public bool CheckEngineBounds(ulong lease, GuaSpatialEngineBounds bounds)
{
bounds.StructSize = (uint)Marshal.SizeOf<GuaSpatialEngineBounds>();
Check(Native.gua_spatial_host_check_engine_bounds(_handle, lease, in bounds, out var loaded, out var e), e);
return loaded != 0;
}
public void End(ulong lease) => Check(Native.gua_spatial_host_end(_handle, lease, out var e), e);
public void Dispose() => _handle.Dispose();
}
Expand All @@ -103,5 +120,6 @@ internal static partial class Native
[DllImport(ValueLibrary, CallingConvention = CallingConvention.Cdecl)] internal static extern int gua_spatial_host_begin(SpatialHostHandle host, ulong provider, nint doc, out ulong lease, out SpatialError e);
[DllImport(ValueLibrary, CallingConvention = CallingConvention.Cdecl)] internal static extern int gua_spatial_host_take(SpatialHostHandle host, ulong lease, out nint doc, out SpatialError e);
[DllImport(ValueLibrary, CallingConvention = CallingConvention.Cdecl)] internal static extern int gua_spatial_host_complete(SpatialHostHandle host, ulong lease, nint doc, out SpatialError e);
[DllImport(ValueLibrary, CallingConvention = CallingConvention.Cdecl)] internal static extern int gua_spatial_host_check_engine_bounds(SpatialHostHandle host, ulong lease, in GuaSpatialEngineBounds bounds, out uint loaded, out SpatialError e);
[DllImport(ValueLibrary, CallingConvention = CallingConvention.Cdecl)] internal static extern int gua_spatial_host_end(SpatialHostHandle host, ulong lease, out SpatialError e);
}
21 changes: 21 additions & 0 deletions bindings/dotnet/tests/Gua.Selector.Tests/SpatialHostTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,27 @@ public void OrderedBoundaryHasOptionalTickAndPartialEnd()
Assert.That(Assert.Throws<GuaSpatialException>(()=>h.Poll(o,1))!.Code,Is.EqualTo(GuaSpatialErrorCode.Stale));
}
[Test]
public void PreparedEngineBoundsUseNativeGrantsAndRemainRevocable()
{
Assert.That(Marshal.SizeOf<GuaSpatialEngineBounds>(),Is.EqualTo(56));
using var h=Host(); using var registration=Doc(0); using var grants=Doc(1); using var batch=Doc(2); using var boundary=Doc(3); using var execution=Doc(4);
var p=h.Register(registration); var o=h.OpenOwner(grants); h.Enqueue(o,batch); var l=h.Begin(p,boundary)!.Value;
try
{
using var q=h.Take(l)!;
var bounds=new GuaSpatialEngineBounds {MinX=-9,MinY=-9,MinZ=-9,MaxX=11,MaxY=9,MaxZ=9};
Assert.That(Assert.Throws<GuaSpatialException>(()=>h.CheckEngineBounds(l,bounds))!.Code,Is.EqualTo(GuaSpatialErrorCode.NotAuthorized));
bounds.MaxX=9; Assert.That(h.CheckEngineBounds(l,bounds),Is.True); h.Complete(l,execution);
h.End(l); l=0;
var narrowed=grants.ReadOwner(); narrowed.Region=narrowed.Region with {Max=new GuaSpatialVector(8,10,10)};
using var updated=GuaSpatialDocument.FromOwner(narrowed); h.SetOwner(o,updated);
using var result=h.Poll(o,1)!;
Assert.That(result.ReadBatchResult().Items[0].Reason,Is.EqualTo("not_authorized"));
Assert.That(result.ReadBatchResult().Items[0].Result,Is.Null);
}
finally {if(l!=0) h.End(l);}
}
[Test]
public void RevocationAndLateCompletionCannotPublishGeometry()
{
using var h=Host(); using var registration=Doc(0); using var grants=Doc(1); using var batch=Doc(2); using var boundary=Doc(3); using var execution=Doc(4);
Expand Down
Loading