using XFESystem.Kernel;
using Xunit;
namespace XFESystem.Desktop.Platform.Tests;
public sealed class NativeRenderYieldPendingTests
{
private static void DrainPointer()
{
NativePointerCapture.Prepare(); while(NativePointerCapture.TryRead(out _)){ }
NativePointerCapture.Observe(0,0,false,false,false,0,0); while(NativePointerCapture.TryRead(out _)){ }
}
private static void DrainKeyboard()
{ NativeKeyboardCapture.Prepare(); while(NativeKeyboardCapture.TryRead(out _,out _,out _)){ } }
[Fact]
public void KeyboardPendingIsReadOnlyUntilEveryMakeBreakIsConsumed()
{
DrainKeyboard(); Assert.False(NativeKeyboardCapture.HasPendingReports);
NativeKeyboardCapture.Observe(0x5B,false); NativeKeyboardCapture.Observe(0x5B,true);
Assert.True(NativeKeyboardCapture.HasPendingReports); Assert.True(NativeKeyboardCapture.HasPendingReports);
Assert.True(NativeKeyboardCapture.TryRead(out var scan,out var released,out var lost)); Assert.Equal(0x5B,scan); Assert.False(released); Assert.False(lost);
Assert.True(NativeKeyboardCapture.HasPendingReports);
Assert.True(NativeKeyboardCapture.TryRead(out scan,out released,out lost)); Assert.True(released); Assert.False(lost);
Assert.False(NativeKeyboardCapture.HasPendingReports);
}
[Fact]
public void MotionAndHeldDragDoNotRequestYieldButEachButtonTransitionDoes()
{
DrainPointer(); Assert.False(NativePointerCapture.HasButtonTransitionPending);
for(int i=0;i<64;i++)NativePointerCapture.Observe(i,i,false,false,false,0,i);
Assert.False(NativePointerCapture.HasButtonTransitionPending);
NativePointerCapture.Observe(70,70,true,false,false,0,70);
Assert.True(NativePointerCapture.HasButtonTransitionPending); Assert.True(NativePointerCapture.HasButtonTransitionPending);
for(int i=0;i<64;i++)Assert.True(NativePointerCapture.TryRead(out _));
Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var down)); Assert.True(down.LeftButton);
Assert.False(NativePointerCapture.HasButtonTransitionPending);
NativePointerCapture.Observe(71,71,true,false,false,0,71); Assert.False(NativePointerCapture.HasButtonTransitionPending);
NativePointerCapture.Observe(72,72,false,false,false,0,72); Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out _)); Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var up)); Assert.False(up.LeftButton); Assert.False(NativePointerCapture.HasButtonTransitionPending);
}
[Fact]
public void MultipleButtonsAndRingWrapKeepUnreadTransitionCountsExact()
{
DrainPointer();
for(int i=0;i<NativePointerCapture.Capacity*3;i++)
{
bool right=(i&1)==0,middle=(i&2)!=0;
NativePointerCapture.Observe(i,i,false,right,middle,0,i);
Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var report)); Assert.Equal(right,report.RightButton); Assert.Equal(middle,report.MiddleButton);
Assert.False(NativePointerCapture.HasButtonTransitionPending);
}
DrainPointer();
}
[Fact]
public void LossYieldsUntilItsSentinelAndSubsequentHeldButtonIsANewTransition()
{
DrainPointer();
for(int i=0;i<NativePointerCapture.Capacity+1;i++)NativePointerCapture.Observe(i,i,true,false,false,0,i);
Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var loss)); Assert.True(loss.LostReports);
Assert.False(NativePointerCapture.HasButtonTransitionPending);
NativePointerCapture.Observe(1,1,true,false,false,0,1); Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var held)); Assert.True(held.LeftButton); Assert.False(held.LostReports);
Assert.False(NativePointerCapture.HasButtonTransitionPending); DrainPointer();
DrainKeyboard(); for(int i=0;i<600;i++)NativeKeyboardCapture.Observe(0x12,false);
Assert.True(NativeKeyboardCapture.HasPendingReports);
Assert.True(NativeKeyboardCapture.TryRead(out _,out _,out var lost)); Assert.True(lost); Assert.False(NativeKeyboardCapture.HasPendingReports);
}
[Fact]
public void PendingObservationAndInterruptDeliveryAllocateNothingAfterPrepare()
{
DrainPointer(); DrainKeyboard();
_=NativeKeyboardCapture.HasPendingReports;_=NativePointerCapture.HasButtonTransitionPending;
long before=GC.GetAllocatedBytesForCurrentThread();
for(int i=0;i<1000;i++)
{
NativeKeyboardCapture.Observe(0x12,false);_=NativeKeyboardCapture.HasPendingReports;NativeKeyboardCapture.TryRead(out _,out _,out _);
NativePointerCapture.Observe(i,i,(i&1)==0,false,false,0,i);_=NativePointerCapture.HasButtonTransitionPending;NativePointerCapture.TryRead(out _);
}
long after=GC.GetAllocatedBytesForCurrentThread();Assert.Equal(before,after);DrainPointer();DrainKeyboard();
}
}
using XFESystem.Kernel;
using Xunit;
namespace XFESystem.Desktop.Platform.Tests;
public sealed class NativeRenderYieldPendingTests
{
private static void DrainPointer()
{
NativePointerCapture.Prepare(); while(NativePointerCapture.TryRead(out _)){ }
NativePointerCapture.Observe(0,0,false,false,false,0,0); while(NativePointerCapture.TryRead(out _)){ }
}
private static void DrainKeyboard()
{ NativeKeyboardCapture.Prepare(); while(NativeKeyboardCapture.TryRead(out _,out _,out _)){ } }
[Fact]
public void KeyboardPendingIsReadOnlyUntilEveryMakeBreakIsConsumed()
{
DrainKeyboard(); Assert.False(NativeKeyboardCapture.HasPendingReports);
NativeKeyboardCapture.Observe(0x5B,false); NativeKeyboardCapture.Observe(0x5B,true);
Assert.True(NativeKeyboardCapture.HasPendingReports); Assert.True(NativeKeyboardCapture.HasPendingReports);
Assert.True(NativeKeyboardCapture.TryRead(out var scan,out var released,out var lost)); Assert.Equal(0x5B,scan); Assert.False(released); Assert.False(lost);
Assert.True(NativeKeyboardCapture.HasPendingReports);
Assert.True(NativeKeyboardCapture.TryRead(out scan,out released,out lost)); Assert.True(released); Assert.False(lost);
Assert.False(NativeKeyboardCapture.HasPendingReports);
}
[Fact]
public void MotionAndHeldDragDoNotRequestYieldButEachButtonTransitionDoes()
{
DrainPointer(); Assert.False(NativePointerCapture.HasButtonTransitionPending);
for(int i=0;i<64;i++)NativePointerCapture.Observe(i,i,false,false,false,0,i);
Assert.False(NativePointerCapture.HasButtonTransitionPending);
NativePointerCapture.Observe(70,70,true,false,false,0,70);
Assert.True(NativePointerCapture.HasButtonTransitionPending); Assert.True(NativePointerCapture.HasButtonTransitionPending);
for(int i=0;i<64;i++)Assert.True(NativePointerCapture.TryRead(out _));
Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var down)); Assert.True(down.LeftButton);
Assert.False(NativePointerCapture.HasButtonTransitionPending);
NativePointerCapture.Observe(71,71,true,false,false,0,71); Assert.False(NativePointerCapture.HasButtonTransitionPending);
NativePointerCapture.Observe(72,72,false,false,false,0,72); Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out _)); Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var up)); Assert.False(up.LeftButton); Assert.False(NativePointerCapture.HasButtonTransitionPending);
}
[Fact]
public void MultipleButtonsAndRingWrapKeepUnreadTransitionCountsExact()
{
DrainPointer();
for(int i=0;i<NativePointerCapture.Capacity*3;i++)
{
bool right=(i&1)==0,middle=(i&2)!=0;
NativePointerCapture.Observe(i,i,false,right,middle,0,i);
Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var report)); Assert.Equal(right,report.RightButton); Assert.Equal(middle,report.MiddleButton);
Assert.False(NativePointerCapture.HasButtonTransitionPending);
}
DrainPointer();
}
[Fact]
public void LossYieldsUntilItsSentinelAndSubsequentHeldButtonIsANewTransition()
{
DrainPointer();
for(int i=0;i<NativePointerCapture.Capacity+1;i++)NativePointerCapture.Observe(i,i,true,false,false,0,i);
Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var loss)); Assert.True(loss.LostReports);
Assert.False(NativePointerCapture.HasButtonTransitionPending);
NativePointerCapture.Observe(1,1,true,false,false,0,1); Assert.True(NativePointerCapture.HasButtonTransitionPending);
Assert.True(NativePointerCapture.TryRead(out var held)); Assert.True(held.LeftButton); Assert.False(held.LostReports);
Assert.False(NativePointerCapture.HasButtonTransitionPending); DrainPointer();
DrainKeyboard(); for(int i=0;i<600;i++)NativeKeyboardCapture.Observe(0x12,false);
Assert.True(NativeKeyboardCapture.HasPendingReports);
Assert.True(NativeKeyboardCapture.TryRead(out _,out _,out var lost)); Assert.True(lost); Assert.False(NativeKeyboardCapture.HasPendingReports);
}
[Fact]
public void PendingObservationAndInterruptDeliveryAllocateNothingAfterPrepare()
{
DrainPointer(); DrainKeyboard();
_=NativeKeyboardCapture.HasPendingReports;_=NativePointerCapture.HasButtonTransitionPending;
long before=GC.GetAllocatedBytesForCurrentThread();
for(int i=0;i<1000;i++)
{
NativeKeyboardCapture.Observe(0x12,false);_=NativeKeyboardCapture.HasPendingReports;NativeKeyboardCapture.TryRead(out _,out _,out _);
NativePointerCapture.Observe(i,i,(i&1)==0,false,false,0,i);_=NativePointerCapture.HasButtonTransitionPending;NativePointerCapture.TryRead(out _);
}
long after=GC.GetAllocatedBytesForCurrentThread();Assert.Equal(before,after);DrainPointer();DrainKeyboard();
}
}