XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
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();
    }
}