feat: migrate legacy playout workflow and scenes
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
using MBN_STOCK_WEBVIEW.Playout.Interop;
|
||||
|
||||
namespace MBN_STOCK_WEBVIEW.Playout.Tests;
|
||||
|
||||
public sealed class DynamicK3dEventHandlerTests
|
||||
{
|
||||
[Fact]
|
||||
public void GeneratedHandler_ImplementsImportedInterfaceAndForwardsOnlyLifecycleCallbacks()
|
||||
{
|
||||
var sink = new RecordingSink();
|
||||
var value = DynamicK3dEventHandlerBuilder.Create(typeof(IFakeK3dEventHandler), sink);
|
||||
var handler = Assert.IsAssignableFrom<IFakeK3dEventHandler>(value);
|
||||
|
||||
handler.OnHello();
|
||||
handler.OnScenePlayed(1, 9, 10);
|
||||
handler.OnCutOut(0, 9, 10);
|
||||
handler.OnStopAll(1);
|
||||
handler.OnIgnored("sensitive value");
|
||||
|
||||
Assert.Equal(
|
||||
new[]
|
||||
{
|
||||
"OnHello:",
|
||||
"OnScenePlayed:1,9,10",
|
||||
"OnCutOut:0,9,10",
|
||||
"OnStopAll:1"
|
||||
},
|
||||
sink.Calls);
|
||||
Assert.Equal(
|
||||
ClassInterfaceType.None,
|
||||
value.GetType().GetCustomAttributes(typeof(ClassInterfaceAttribute), inherit: false)
|
||||
.Cast<ClassInterfaceAttribute>()
|
||||
.Single()
|
||||
.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EventQueue_ParsesCallbacksWithoutThrowingAcrossNativeBoundary()
|
||||
{
|
||||
var queue = new K3dEventQueue(capacity: 4);
|
||||
|
||||
queue.OnCallback("OnHello", []);
|
||||
queue.OnCallback("OnScenePlayed", [1, 9, 10]);
|
||||
queue.OnCallback("OnCutOut", [0, 9, 10]);
|
||||
queue.OnCallback("OnStopAll", [1]);
|
||||
queue.OnCallback("OnScenePlayed", ["invalid"]);
|
||||
|
||||
Assert.True(queue.HelloObserved);
|
||||
Assert.False(queue.HasOverflowed);
|
||||
Assert.Equal(3, queue.PendingCount);
|
||||
Assert.True(queue.TryDequeue(out var played));
|
||||
Assert.Equal(
|
||||
new K3dLifecycleCallback(K3dLifecycleCallbackKind.ScenePlayed, true, 9, 10),
|
||||
played);
|
||||
Assert.True(queue.TryDequeue(out var cut));
|
||||
Assert.False(cut.IsSuccess);
|
||||
Assert.True(queue.TryDequeue(out var stopped));
|
||||
Assert.Equal(K3dLifecycleCallbackKind.StopAll, stopped.Kind);
|
||||
Assert.False(queue.TryDequeue(out _));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EventQueue_OverflowLatchesAndNeverExceedsCapacity()
|
||||
{
|
||||
var queue = new K3dEventQueue(capacity: 1);
|
||||
|
||||
queue.OnCallback("OnStopAll", [1]);
|
||||
queue.OnCallback("OnStopAll", [1]);
|
||||
|
||||
Assert.True(queue.HasOverflowed);
|
||||
Assert.Equal(1, queue.PendingCount);
|
||||
Assert.True(queue.TryDequeue(out _));
|
||||
Assert.False(queue.TryDequeue(out _));
|
||||
}
|
||||
|
||||
private sealed class RecordingSink : IK3dEventSink
|
||||
{
|
||||
private readonly ConcurrentQueue<string> _calls = new();
|
||||
|
||||
public string[] Calls => _calls.ToArray();
|
||||
|
||||
public void OnCallback(string methodName, object?[] arguments) =>
|
||||
_calls.Enqueue($"{methodName}:{string.Join(',', arguments)}");
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("C21817DB-C0D3-4647-8D85-027338DCF832")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface IFakeK3dEventHandler
|
||||
{
|
||||
void OnHello();
|
||||
|
||||
void OnScenePlayed(int success, int outputChannelIndex, int layerIndex);
|
||||
|
||||
void OnCutOut(int success, int outputChannelIndex, int layerIndex);
|
||||
|
||||
void OnStopAll(int success);
|
||||
|
||||
void OnIgnored(string value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user