토네이도 연결 및 송출 확인

This commit is contained in:
2026-04-14 14:36:03 +09:00
parent 28e2806678
commit e29267c530
10 changed files with 703 additions and 35 deletions

View File

@@ -1,13 +1,12 @@
<Solution>
<Configurations>
<Platform Name="ARM64" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
<Project Path="Tornado3_2026Election/Tornado3_2026Election.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
<Platform Solution="*|x86" Project="x86" />
<Deploy />
</Project>
<Project Path="tools/KarismaTcpProbe/KarismaTcpProbe.csproj">
<Platform Solution="*|x64" Project="x64" />
</Project>
</Solution>

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Tornado3_2026Election.Services;
namespace Tornado3_2026Election.Persistence;
@@ -10,7 +11,7 @@ public sealed class AppState
public string SelectedStationId { get; set; } = "KNN";
public string ImageRootPath { get; set; } = @"C:\Users\y2keu\Downloads\T3_Cut";
public string ImageRootPath { get; set; } = TornadoPathResolver.GetDefaultT3CutPath();
public bool AutoRestoreSchedules { get; set; } = true;
@@ -48,4 +49,3 @@ public sealed class AppState
public Dictionary<string, string> StationRegionFilters { get; set; } = [];
}

View File

@@ -86,10 +86,20 @@ public sealed class KarismaTornado3Adapter : ITornado3Adapter, IDisposable
logService.Info($"Karisma adapter using default port {DefaultKarismaPort}.");
}
var t3CutPath = t3CutPathProvider();
var configuredT3CutPath = t3CutPathProvider();
var t3CutPath = string.IsNullOrWhiteSpace(configuredT3CutPath)
? TornadoPathResolver.GetDefaultT3CutPath()
: TornadoPathResolver.NormalizeConfiguredPath(configuredT3CutPath);
if (!string.Equals(configuredT3CutPath, t3CutPath, StringComparison.OrdinalIgnoreCase) &&
!string.IsNullOrWhiteSpace(t3CutPath))
{
logService.Info($"Karisma adapter normalized T3_Cut path to '{t3CutPath}'.");
}
if (string.IsNullOrWhiteSpace(t3CutPath) || !Directory.Exists(t3CutPath))
{
logService.Warning("Karisma adapter disabled: set a valid T3_Cut path in Settings.");
logService.Warning($"Karisma adapter disabled: set a valid T3_Cut path in Settings. current='{configuredT3CutPath}'");
adapter = new MockTornado3Adapter(logService);
return false;
}
@@ -230,7 +240,11 @@ public sealed class KarismaTornado3Adapter : ITornado3Adapter, IDisposable
private string ResolveT3CutPath()
{
var path = _t3CutPathProvider();
var configuredPath = _t3CutPathProvider();
var path = string.IsNullOrWhiteSpace(configuredPath)
? TornadoPathResolver.GetDefaultT3CutPath()
: TornadoPathResolver.NormalizeConfiguredPath(configuredPath);
if (string.IsNullOrWhiteSpace(path) || !Directory.Exists(path))
{
throw new DirectoryNotFoundException("T3_Cut path is not configured or does not exist.");

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using KAsyncEngineLib;
@@ -372,9 +373,14 @@ public sealed class TornadoManager : IDisposable
private sealed class StaDispatcher : IDisposable
{
private readonly BlockingCollection<Action> _queue = new();
private const uint WmApp = 0x8000;
private const uint WmDispatch = WmApp + 1;
private readonly ConcurrentQueue<Action> _queue = new();
private readonly Thread _thread;
private readonly ManualResetEventSlim _threadReady = new();
private bool _disposed;
private uint _threadId;
public StaDispatcher(string threadName)
{
@@ -385,6 +391,7 @@ public sealed class TornadoManager : IDisposable
};
_thread.SetApartmentState(ApartmentState.STA);
_thread.Start();
_threadReady.Wait();
}
public Task InvokeAsync(Action action, CancellationToken cancellationToken)
@@ -402,18 +409,29 @@ public sealed class TornadoManager : IDisposable
cancellationToken.ThrowIfCancellationRequested();
var completion = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
_queue.Add(() =>
_queue.Enqueue(() =>
{
if (cancellationToken.IsCancellationRequested)
{
completion.TrySetCanceled(cancellationToken);
return;
}
try
{
completion.SetResult(action());
completion.TrySetResult(action());
}
catch (Exception ex)
{
completion.SetException(ex);
completion.TrySetException(ex);
}
});
if (!PostThreadMessage(_threadId, WmDispatch, UIntPtr.Zero, IntPtr.Zero))
{
throw new InvalidOperationException("Failed to signal Karisma STA dispatcher.");
}
return cancellationToken.CanBeCanceled
? completion.Task.WaitAsync(cancellationToken)
: completion.Task;
@@ -427,17 +445,77 @@ public sealed class TornadoManager : IDisposable
}
_disposed = true;
_queue.CompleteAdding();
PostThreadMessage(_threadId, WmQuit, UIntPtr.Zero, IntPtr.Zero);
_thread.Join();
_queue.Dispose();
_threadReady.Dispose();
}
private void Run()
{
foreach (var action in _queue.GetConsumingEnumerable())
PeekMessage(out _, IntPtr.Zero, 0, 0, 0);
_threadId = GetCurrentThreadId();
_threadReady.Set();
while (GetMessage(out var message, IntPtr.Zero, 0, 0) > 0)
{
if (message.message == WmDispatch)
{
DrainQueue();
continue;
}
TranslateMessage(ref message);
DispatchMessage(ref message);
}
DrainQueue();
}
private void DrainQueue()
{
while (_queue.TryDequeue(out var action))
{
action();
}
}
private const uint WmQuit = 0x0012;
[DllImport("kernel32.dll")]
private static extern uint GetCurrentThreadId();
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostThreadMessage(uint idThread, uint msg, UIntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern int GetMessage(out NativeMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
[DllImport("user32.dll")]
private static extern bool TranslateMessage([In] ref NativeMessage lpMsg);
[DllImport("user32.dll")]
private static extern IntPtr DispatchMessage([In] ref NativeMessage lpMsg);
[DllImport("user32.dll")]
private static extern bool PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
[StructLayout(LayoutKind.Sequential)]
private struct NativeMessage
{
public IntPtr hwnd;
public uint message;
public UIntPtr wParam;
public IntPtr lParam;
public uint time;
public NativePoint pt;
public uint lPrivate;
}
[StructLayout(LayoutKind.Sequential)]
private struct NativePoint
{
public int x;
public int y;
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Tornado3_2026Election.Services;
public static class TornadoPathResolver
{
public static string GetDefaultT3CutPath()
{
foreach (var candidate in GetCandidatePaths())
{
var normalized = NormalizeConfiguredPath(candidate);
if (!string.IsNullOrWhiteSpace(normalized) && Directory.Exists(normalized))
{
return normalized;
}
}
return NormalizeConfiguredPath(Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"Tornado3 Data",
"T3_Cut",
"T3_Cut"));
}
public static string NormalizeConfiguredPath(string? configuredPath)
{
if (string.IsNullOrWhiteSpace(configuredPath))
{
return string.Empty;
}
var trimmedPath = configuredPath.Trim();
if (!Directory.Exists(trimmedPath))
{
return trimmedPath;
}
var nestedDefault = Path.Combine(trimmedPath, "T3_Cut");
if (ContainsSceneFiles(nestedDefault))
{
return nestedDefault;
}
if (ContainsSceneFiles(trimmedPath))
{
return trimmedPath;
}
var nestedDirectory = TryFindNestedSceneDirectory(trimmedPath);
return nestedDirectory ?? trimmedPath;
}
private static IEnumerable<string> GetCandidatePaths()
{
var userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var configured = Environment.GetEnvironmentVariable("TORNADO_T3CUT_PATH");
if (!string.IsNullOrWhiteSpace(configured))
{
yield return configured;
}
if (!string.IsNullOrWhiteSpace(documents))
{
yield return Path.Combine(documents, "Tornado3 Data", "T3_Cut", "T3_Cut");
yield return Path.Combine(documents, "Tornado3 Data", "T3_Cut");
}
if (!string.IsNullOrWhiteSpace(userProfile))
{
yield return Path.Combine(userProfile, "Downloads", "T3_Cut");
}
}
private static string? TryFindNestedSceneDirectory(string rootPath)
{
try
{
return Directory.EnumerateDirectories(rootPath, "*", SearchOption.TopDirectoryOnly)
.Select(NormalizeConfiguredPath)
.FirstOrDefault(path => !string.IsNullOrWhiteSpace(path) && ContainsSceneFiles(path));
}
catch
{
return null;
}
}
private static bool ContainsSceneFiles(string? path)
{
if (string.IsNullOrWhiteSpace(path) || !Directory.Exists(path))
{
return false;
}
try
{
return Directory.EnumerateFiles(path, "*.tscn", SearchOption.AllDirectories).Any();
}
catch
{
return false;
}
}
}

View File

@@ -6,24 +6,20 @@
<RootNamespace>Tornado3_2026Election</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationIcon>Assets\AppIcon.ico</ApplicationIcon>
<Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<Platforms>x64</Platforms>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<UseWinUI>true</UseWinUI>
<WinUISDKReferences>false</WinUISDKReferences>
<EnableMsixTooling>true</EnableMsixTooling>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='' and ('$(Platform)'=='' or '$(Platform)'=='AnyCPU' or '$(Platform)'=='x64')">
<PropertyGroup Condition="'$(RuntimeIdentifier)'==''">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='' and '$(Platform)'=='x86'">
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='' and '$(Platform)'=='ARM64'">
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
<PropertyGroup>
<KarismaSdkDir Condition="'$(KarismaSdkDir)'==''">C:\Karisma SDK</KarismaSdkDir>
</PropertyGroup>
<PropertyGroup Condition="Exists('Properties\PublishProfiles\win-$(Platform).pubxml')">
@@ -89,7 +85,7 @@
</ItemGroup>
<ItemGroup>
<Reference Include="Interop.KAsyncEngineLib">
<HintPath>..\..\..\..\..\..\Karisma SDK\Bin\C#\Interop.KAsyncEngineLib.dll</HintPath>
<HintPath>$(KarismaSdkDir)\Bin\C#\Interop.KAsyncEngineLib.dll</HintPath>
</Reference>
</ItemGroup>
<PropertyGroup Label="Globals">

View File

@@ -24,6 +24,7 @@ public sealed class MainViewModel : ObservableObject
private readonly FormatCatalogService _formatCatalogService;
private readonly AppStateStore _stateStore;
private readonly LogService _logService;
private readonly ITornado3Adapter _sharedTornadoAdapter;
private readonly SemaphoreSlim _stateSaveLock = new(1, 1);
private AppPage _currentPage = AppPage.IntegratedSchedule;
private ChannelOperationMode _operationMode = ChannelOperationMode.General;
@@ -56,11 +57,12 @@ public sealed class MainViewModel : ObservableObject
Settings.PropertyChanged += Settings_PropertyChanged;
Data.PropertyChanged += Data_PropertyChanged;
_sharedTornadoAdapter = KarismaTornado3Adapter.CreateOrFallback(_logService, () => Settings.ImageRootPath);
NormalChannel = CreateChannelViewModel(BroadcastChannel.Normal, "노멀");
TopLeftChannel = CreateChannelViewModel(BroadcastChannel.TopLeft, "좌상단");
BottomChannel = CreateChannelViewModel(BroadcastChannel.Bottom, "하단");
VideoWallChannel = CreateChannelViewModel(BroadcastChannel.VideoWall, "비디오월");
NormalChannel = CreateChannelViewModel(BroadcastChannel.Normal, "노멀", _sharedTornadoAdapter);
TopLeftChannel = CreateChannelViewModel(BroadcastChannel.TopLeft, "좌상단", _sharedTornadoAdapter);
BottomChannel = CreateChannelViewModel(BroadcastChannel.Bottom, "하단", _sharedTornadoAdapter);
VideoWallChannel = CreateChannelViewModel(BroadcastChannel.VideoWall, "비디오월", _sharedTornadoAdapter);
Channels = [NormalChannel, TopLeftChannel, BottomChannel, VideoWallChannel];
foreach (var channel in Channels)
@@ -82,6 +84,7 @@ public sealed class MainViewModel : ObservableObject
_logService.Entries.CollectionChanged += (_, _) => RebuildFilteredLogs();
SelectedLogFilterOption = LogFilterOptions[0];
_logService.Info("SYSTEM_SPEC 기반 MVVM 구조를 초기화했습니다.");
_ = WarmupSharedCgConnectionAsync();
}
public DataViewModel Data { get; }
@@ -439,6 +442,7 @@ public sealed class MainViewModel : ObservableObject
}
_logService.Info("저장한 시작 옵션에 따라 상태를 자동 복원했습니다.");
_ = WarmupSharedCgConnectionAsync();
}
public async Task RestoreAsync()
@@ -471,6 +475,11 @@ public sealed class MainViewModel : ObservableObject
public async Task ShutdownAsync()
{
await SaveStateCoreAsync(writeLog: false);
if (_sharedTornadoAdapter is IDisposable disposableAdapter)
{
disposableAdapter.Dispose();
}
Data.Dispose();
}
@@ -520,6 +529,7 @@ public sealed class MainViewModel : ObservableObject
if (args.PropertyName is nameof(SettingsViewModel.SelectedStationId) or nameof(SettingsViewModel.ImageRootPath))
{
QueueAutomaticSave();
_ = WarmupSharedCgConnectionAsync();
}
}
@@ -694,9 +704,25 @@ public sealed class MainViewModel : ObservableObject
}
}
private ChannelScheduleViewModel CreateChannelViewModel(BroadcastChannel channel, string title)
private async Task WarmupSharedCgConnectionAsync()
{
if (!_sharedTornadoAdapter.IsLiveCg)
{
return;
}
try
{
await _sharedTornadoAdapter.EnsureConnectedAsync(CancellationToken.None).ConfigureAwait(false);
}
catch (Exception ex)
{
_logService.Warning($"CG startup connection attempt failed: {ex.Message}");
}
}
private ChannelScheduleViewModel CreateChannelViewModel(BroadcastChannel channel, string title, ITornado3Adapter adapter)
{
var adapter = KarismaTornado3Adapter.CreateOrFallback(_logService, () => Settings.ImageRootPath);
var queue = new ObservableCollection<ChannelScheduleItem>();
var engine = new ChannelScheduleEngine(
channel,

View File

@@ -3,13 +3,14 @@ using System.Collections.ObjectModel;
using System.Linq;
using Tornado3_2026Election.Common;
using Tornado3_2026Election.Domain;
using Tornado3_2026Election.Services;
namespace Tornado3_2026Election.ViewModels;
public sealed class SettingsViewModel : ObservableObject
{
private string _selectedStationId = "KNN";
private string _imageRootPath = @"C:\Users\y2keu\Downloads\T3_Cut";
private string _imageRootPath = TornadoPathResolver.GetDefaultT3CutPath();
public SettingsViewModel(IEnumerable<BroadcastStationProfile> stations)
{
@@ -50,7 +51,7 @@ public sealed class SettingsViewModel : ObservableObject
public string ImageRootPath
{
get => _imageRootPath;
set => SetProperty(ref _imageRootPath, value);
set => SetProperty(ref _imageRootPath, TornadoPathResolver.NormalizeConfiguredPath(value));
}
public StationFilterItemViewModel SelectedStation

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<KarismaSdkDir Condition="'$(KarismaSdkDir)'==''">C:\Karisma SDK</KarismaSdkDir>
</PropertyGroup>
<ItemGroup>
<Reference Include="Interop.KAsyncEngineLib">
<HintPath>$(KarismaSdkDir)\Bin\C#\Interop.KAsyncEngineLib.dll</HintPath>
<Private>true</Private>
</Reference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,426 @@
using System;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using KAsyncEngineLib;
var options = ProbeOptions.Parse(args);
Console.WriteLine($"Karisma TCP probe starting. target={options.Host}:{options.Port} timeout={options.Timeout.TotalSeconds:0}s");
var rawTcpOk = await ProbeRawTcpAsync(options).ConfigureAwait(false);
var sdkResult = await ProbeSdkAsync(options).ConfigureAwait(false);
Console.WriteLine();
Console.WriteLine("Summary");
Console.WriteLine($"- Raw TCP: {(rawTcpOk ? "OK" : "FAILED")}");
Console.WriteLine($"- SDK Connect(): {(sdkResult.ConnectRequestAccepted ? "ACCEPTED" : "REJECTED")}");
Console.WriteLine($"- SDK OnConnect: {sdkResult.ConnectOutcome}");
Console.WriteLine($"- SDK Detail: {sdkResult.Detail}");
Environment.ExitCode = rawTcpOk && sdkResult.ConnectRequestAccepted && sdkResult.ConnectOutcome == "SUCCESS"
? 0
: 1;
static async Task<bool> ProbeRawTcpAsync(ProbeOptions options)
{
try
{
using var client = new TcpClient();
using var cts = new CancellationTokenSource(options.Timeout);
await client.ConnectAsync(options.Host, options.Port, cts.Token).ConfigureAwait(false);
Console.WriteLine($"[RAW] Connected local={client.Client.LocalEndPoint} remote={client.Client.RemoteEndPoint}");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"[RAW] Failed: {ex.Message}");
return false;
}
}
static Task<SdkProbeResult> ProbeSdkAsync(ProbeOptions options)
{
var completion = new TaskCompletionSource<SdkProbeResult>(TaskCreationOptions.RunContinuationsAsynchronously);
var thread = new Thread(() =>
{
try
{
var handler = new ProbeEventHandler();
var engine = (IKAEngine)new KAEngineClass();
Console.WriteLine("[SDK] Calling Connect()...");
var connectRequested = engine.Connect(options.Host, options.Port, handler);
Console.WriteLine($"[SDK] Connect() returned {(connectRequested != 0 ? "TRUE" : "FALSE")} raw={connectRequested}");
if (connectRequested == 0)
{
completion.TrySetResult(new SdkProbeResult(false, "FAILED", "Connect() returned 0."));
return;
}
if (!WaitForTaskWithMessagePump(handler.ConnectTask, options.Timeout))
{
completion.TrySetResult(new SdkProbeResult(true, "TIMEOUT", $"OnConnect was not received within {options.Timeout.TotalSeconds:0} seconds."));
return;
}
var errorCode = handler.ConnectTask.Result;
var outcome = errorCode == 0 ? "SUCCESS" : "FAILED";
completion.TrySetResult(new SdkProbeResult(true, outcome, $"OnConnect errorCode={errorCode}"));
try
{
engine.Disconnect();
handler.CloseTask.Wait(TimeSpan.FromSeconds(2));
}
catch
{
}
}
catch (Exception ex)
{
completion.TrySetResult(new SdkProbeResult(false, "EXCEPTION", ex.ToString()));
}
})
{
IsBackground = true,
Name = "KarismaTcpProbe"
};
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return completion.Task;
}
static bool WaitForTaskWithMessagePump(Task task, TimeSpan timeout)
{
User32.PeekMessage(out _, IntPtr.Zero, 0, 0, 0);
var deadline = DateTime.UtcNow + timeout;
while (!task.IsCompleted)
{
while (User32.PeekMessage(out var message, IntPtr.Zero, 0, 0, 1))
{
User32.TranslateMessage(ref message);
User32.DispatchMessage(ref message);
}
if (DateTime.UtcNow >= deadline)
{
return false;
}
Thread.Sleep(10);
}
return true;
}
internal sealed record ProbeOptions(string Host, int Port, TimeSpan Timeout)
{
public static ProbeOptions Parse(string[] args)
{
var host = "127.0.0.1";
var port = 30001;
var timeout = TimeSpan.FromSeconds(5);
for (var index = 0; index < args.Length; index++)
{
switch (args[index])
{
case "--host" when index + 1 < args.Length:
host = args[++index];
break;
case "--port" when index + 1 < args.Length && int.TryParse(args[index + 1], out var parsedPort):
port = parsedPort;
index++;
break;
case "--timeout" when index + 1 < args.Length && double.TryParse(args[index + 1], out var parsedTimeoutSeconds):
timeout = TimeSpan.FromSeconds(parsedTimeoutSeconds);
index++;
break;
}
}
return new ProbeOptions(host, port, timeout);
}
}
internal sealed record SdkProbeResult(bool ConnectRequestAccepted, string ConnectOutcome, string Detail);
internal sealed class ProbeEventHandler : KAEventHandler
{
private readonly TaskCompletionSource<int> _connectTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private readonly TaskCompletionSource<int> _closeTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
public Task<int> ConnectTask => _connectTask.Task;
public Task<int> CloseTask => _closeTask.Task;
public void OnConnect(int ErrorCode)
{
Console.WriteLine($"[SDK] OnConnect errorCode={ErrorCode}");
_connectTask.TrySetResult(ErrorCode);
}
public void OnClose(int ErrorCode)
{
Console.WriteLine($"[SDK] OnClose errorCode={ErrorCode}");
_closeTask.TrySetResult(ErrorCode);
}
public void OnLoadScene(eKResult Result, string SceneName) { }
public void OnLoadSceneForce(eKResult Result, string SceneName) { }
public void OnLogMessage(string LogMessage) { }
public void OnMessageNo(uint MessageNo) { }
public void OnBeginTransaction(eKResult Result) { }
public void OnEndTransaction(eKResult Result) { }
public void OnHeartBeat(eKResult Result) { }
public void OnUnloadAll(eKResult Result) { }
public void OnSetTrialPlayoutMode(eKResult Result) { }
public void OnCheckVersion(eKResult Result, string ServerVersion, string SDKVersion) { }
public void OnSetAudioOutput(eKResult Result) { }
public void OnScenePrepare(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnScenePrepareEx(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnPlay(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnPlayOut(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnStop(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnStopAll(eKResult Result) { }
public void OnPause(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnResume(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnQueryIsOnAir(eKResult Result, int OutputChannelIndex, int LayerNo, int bOnAir) { }
public void OnTrigger(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnScenePlayingStarted(string SceneName, int OutputChannelIndex, int LayerNo) { }
public void OnScenePlayed(string SceneName, int OutputChannelIndex, int LayerNo) { }
public void OnSceneAnimationPlayed(string SceneName, int OutputChannelIndex, int LayerNo, string AnimationName) { }
public void OnScenePaused(string SceneName, int OutputChannelIndex, int LayerNo, int bLastPause) { }
public void OnSceneSaved(eKResult Result, string FileName) { }
public void OnTriggerObject(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnResumeBackground(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnSaveMixedPreviewImage(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnPlayDirect(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnCutIn(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnCutOut(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnClearNextPreview(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnPlayRange(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnQueryPlaybackRangeCount(eKResult Result, string SceneName, int PlaybackRangeCount) { }
public void OnQueryPlaybackRange(eKResult Result, string SceneName, int PlaybackRangeNo, int Start, int End) { }
public void OnQueryOutputChannelIndex(eKResult Result, string SceneName, int OutputChannelIndex) { }
public void OnPlayInNextPreview(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnPlayOutNextPreview(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnSetBackgroundFill(eKResult Result, string SceneName) { }
public void OnSetBackgroundTexture(eKResult Result, string SceneName) { }
public void OnSetBackgroundVideo(eKResult Result, string SceneName) { }
public void OnSetBackgroundLiveIn(eKResult Result, string SceneName) { }
public void OnUseBackground(eKResult Result, string SceneName) { }
public void OnSetBackgroundVideoPlayInfo(eKResult Result, string SceneName) { }
public void OnQueryBackgroundVideoPlayInfo(eKResult Result, string SceneName, ref sKVideoPlayInfo pVideoPlayInfo) { }
public void OnSetSceneEffectType(eKResult Result, string SceneName) { }
public void OnSaveSceneImage(eKResult Result, string SceneName) { }
public void OnSaveScene(eKResult Result, string SceneName) { }
public void OnUnloadScene(eKResult Result, string SceneName) { }
public void OnReloadScene(eKResult Result, string SceneName) { }
public void OnUpdateTextures(eKResult Result, string SceneName) { }
public void OnSetSceneAudioFile(eKResult Result, string SceneName) { }
public void OnEnableSceneAudio(eKResult Result, string SceneName) { }
public void OnSetSceneDuration(eKResult Result, string SceneName) { }
public void OnSetBackgroundPauseType(eKResult Result, string SceneName) { }
public void OnSetBackgroundChangeType(eKResult Result, string SceneName) { }
public void OnSetBackgroundPauseAtZeroFrameAsStandBy(eKResult Result, string SceneName) { }
public void OnResetDuration(eKResult Result, string SceneName) { }
public void OnSetDuration(eKResult Result, string SceneName) { }
public void OnAddObject(eKResult Result, string SceneName) { }
public void OnAddCloneObject(eKResult Result, string SceneName) { }
public void OnUpdateThumbnail(eKResult Result, string SceneName) { }
public void OnExportVideo(eKResult Result, string SceneName) { }
public void OnStopVideoExporting(eKResult Result) { }
public void OnQueryVideoExportingProgress(eKResult Result, string TargetName, int CurrentFrame, int TotalFrame) { }
public void OnFinishedVideoExporting(eKResult Result, string FileName) { }
public void OnAddPause(eKResult Result, string SceneName) { }
public void OnDeletePause(eKResult Result, string SceneName) { }
public void OnSetPause(eKResult Result, string SceneName) { }
public void OnSetPauseWithIndex(eKResult Result, string SceneName) { }
public void OnDeletePauseWithIndex(eKResult Result, string SceneName) { }
public void OnQueryPauseCount(eKResult Result, string SceneName, int PauseCount) { }
public void OnQueryObjectInfos(eKResult Result, string SceneName, KAObjectInfos pObjectInfos) { }
public void OnQueryAnimationNames(eKResult Result, string SceneName, KAStrings pAnimationNames) { }
public void OnQueryAnimationCount(eKResult Result, string SceneName, int AnimationCount) { }
public void OnQueryObjectInfosByScreenPoint(eKResult Result, KAObjectInfos pObjectInfos) { }
public void OnQuerySceneEffectType(eKResult Result, string SceneName, int bInEffect, eKEffectType EffectType, int Duration) { }
public void OnQueryDuration(eKResult Result, string SceneName, string AnimationName, int Duration) { }
public void OnQueryContentsOfTextObjects(eKResult Result, string SceneName, KAStrings pTexts) { }
public void OnSetStyleColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetStyleTexture(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetFaceTextColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetEdgeTextColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetShadowTextColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetVisible(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetValue(eKResult Result, string SceneName, string ObjectName) { }
public void OnAddText(eKResult Result, string SceneName, string ObjectName) { }
public void OnStoreTextStyle(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetTextStyle(eKResult Result, string SceneName, string ObjectName) { }
public void OnEditText(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetFont(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetTextRange(eKResult Result, string SceneName, string ObjectName) { }
public void OnResetTextRange(eKResult Result, string SceneName, string ObjectName) { }
public void OnQueryObjectType(eKResult Result, string SceneName, string ObjectName, eKObjectType ObjectType) { }
public void OnSetChartCSVFile(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetChartCellData(eKResult Result, string SceneName, string ObjectName) { }
public void OnQueryChartDataTable(eKResult Result, string SceneName, string ObjectName, KAChartDataTable Table) { }
public void OnQuerySize(eKResult Result, string SceneName, string ObjectName, float Width, float Height) { }
public void OnSetSize(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCounterNumberKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetPositionKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetRotationKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetScaleKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCylinderAngleKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetSphereAngleKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCircleAngleKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCropKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCountDown(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetPosition(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetRotation(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetScale(eKResult Result, string SceneName, string ObjectName) { }
public void OnAddPathPoint(eKResult Result, string SceneName, string ObjectName) { }
public void OnClearPathPoints(eKResult Result, string SceneName, string ObjectName) { }
public void OnAddPathShapePoint(eKResult Result, string SceneName, string ObjectName) { }
public void OnClearPathShapePoints(eKResult Result, string SceneName, string ObjectName) { }
public void OnQueryScrollRemainingDistance(eKResult Result, string SceneName, string ObjectName, int ScrollRemainingDistance) { }
public void OnQueryScrollChildRemainingDistance(eKResult Result, string SceneName, string ObjectName, string ChildName, int ScrollRemainingDistance) { }
public void OnAddScrollObject(eKResult Result, string SceneName, string ObjectName) { }
public void OnAdjustScrollSpeed(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetScrollSpeed(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetVariableName(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetLoftPositionKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetChangeOut(eKResult Result, string SceneName) { }
public void OnModifyPathPoint(eKResult Result, string SceneName, string ObjectName) { }
public void OnInitScrollObject(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCounterInfo(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCounterNumber(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCounterRange(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCounterRemainingTime(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetCounterElapsedTime(eKResult Result, string SceneName, string ObjectName) { }
public void OnSaveObjectImage(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetPositionOfPathAnimation(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetPositionKeyOfPathAnimation(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetStartFrame(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetObjectEffectType(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetObjectOutEffectDelay(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetColorKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetEmissiveColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetEmissiveColorKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetTransparencyOpacity(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetTransparencyOpacityKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetExposure(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetExposureKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureType(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureFile(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureOffset(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureOffsetKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureTiling(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureTilingKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureRotation(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureRotationKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureOpacity(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureOpacityKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnQueryGroupType(eKResult Result, string SceneName, string ObjectName, eKGroupType GroupType) { }
public void OnQueryImageType(eKResult Result, string SceneName, string ObjectName, eKImageType ImageType) { }
public void OnSetVideoPlayInfo(eKResult Result, string SceneName, string ObjectName) { }
public void OnQueryVideoPlayInfo(eKResult Result, string SceneName, string ObjectName, ref sKVideoPlayInfo pVideoPlayInfo) { }
public void OnQueryIs3D(eKResult Result, string SceneName, string ObjectName, int b3D) { }
public void OnQueryPosition(eKResult Result, string SceneName, string ObjectName, float X, float Y, float Z) { }
public void OnSetImageType(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMemo(eKResult Result, string SceneName, string ObjectName) { }
public void OnQueryMemo(eKResult Result, string SceneName, string ObjectName, string Memo) { }
public void OnQueryFont(eKResult Result, string SceneName, string ObjectName, ref sKFont Param) { }
public void OnSetImageOriginalSize(eKResult Result, string SceneName, string ObjectName) { }
public void OnApplyChangeEffectLibrary(eKResult Result, string SceneName) { }
public void OnApplyObjectLibrary(eKResult Result, string SceneName, string ObjectName) { }
public void OnApplyTextureEffectLibrary(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetTableValue(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetTableColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnQueryTableValue(eKResult Result, string SceneName, string ObjectName, int Row, int Column, string Value) { }
public void OnQueryTableValues(eKResult Result, string SceneName, string ObjectName, KATableValues pValues) { }
public void OnSetPathShapeOutlineThickness(eKResult Result, string SceneName, string ObjectName) { }
public void OnEnablePathShapeOutline(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetPlaybackCamera(eKResult Result, string SceneName) { }
public void OnSetMaterialTextureVideoPlayInfo(eKResult Result, string SceneName, string ObjectName) { }
public void OnQueryMaterialTextureVideoPlayInfo(eKResult Result, string SceneName, string ObjectName, ref sKVideoPlayInfo VideoPlayInfo) { }
public void OnQueryVideoFormat(eKResult Result, ref sKVideoFormat VideoFormat) { }
public void OnQueryLiveStreamingStatus(eKResult Result, string StreamingURI, eKLiveStreamingStatus Status) { }
public void OnPreloadLiveStreaming(eKResult Result, string StreamingURI) { }
public void OnReleaseLiveStreaming(eKResult Result, string StreamingURI) { }
public void OnUpdateImageResource(eKResult Result) { }
public void OnQueryLayerCount(eKResult Result, int LayerCount) { }
public void OnSetLayerViewportRate(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnSetLayerViewportRateEx(eKResult Result, int OutputChannelIndex, int LayerNo) { }
public void OnSetFitting(eKResult Result, string SceneName) { }
public void OnSetFittingOffset(eKResult Result, string SceneName) { }
public void OnSetFittingScale(eKResult Result, string SceneName) { }
public void OnSetLightColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnEnableLight(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetDirectionalLight(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetPointLight(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetSpotLight(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetInfinitePointLight(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetMaterialTextureLiveStreamingURI(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetBackgroundLiveStreamingURI(eKResult Result, string SceneName) { }
public void OnLoadProject(eKResult Result, string FilePath, string AliasName) { }
public void OnNewProject(eKResult Result, string AliasName) { }
public void OnUnloadAllProject(eKResult Result) { }
public void OnSaveProject(eKResult Result, string AliasName) { }
public void OnQuerySceneItemCount(eKResult Result, string AliasName, int SceneItemCount) { }
public void OnQuerySceneItemInfos(eKResult Result, string AliasName, KASceneItemInfos SceneItemInfos) { }
public void OnAddSceneItem(eKResult Result, string AliasName, int Index) { }
public void OnInsertSceneItem(eKResult Result, string AliasName) { }
public void OnDeleteSceneItem(eKResult Result, string AliasNAme) { }
public void OnQueryProjectFormat(eKResult Result, ref sKVideoFormat ProjectFormat) { }
public void OnSetTimecode(eKResult Result, string AliasName) { }
public void OnSetTimecodeInOut(eKResult Result, string AliasName) { }
public void OnSetTimecodeTrack(eKResult Result, string AliasName) { }
public void OnSetTimecodeInOutType(eKResult Result, string AliasName) { }
public void OnDeleteTimecode(eKResult Result, string AliasName) { }
public void OnQueryTimecode(eKResult Result, int TrackNo, int In, int Out, int bOnTrack) { }
public void OnUnloadProject(eKResult Result, string AliasName) { }
public void OnEnableSyncWithSceneEffect(eKResult Result, string AliasName) { }
public void OnExportProjectVideo(eKResult Result, string AliasName) { }
public void OnExportSceneImage(eKResult Result, string SceneName) { }
public void OnStartVideoCapture(eKResult Result) { }
public void OnStopVideoCapture(eKResult Result) { }
public void OnCaptureImage(eKResult Result) { }
}
[StructLayout(LayoutKind.Sequential)]
internal struct NativeMessage
{
public IntPtr hwnd;
public uint message;
public UIntPtr wParam;
public IntPtr lParam;
public uint time;
public NativePoint pt;
public uint lPrivate;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NativePoint
{
public int x;
public int y;
}
internal static class User32
{
[DllImport("user32.dll")]
internal static extern bool PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
[DllImport("user32.dll")]
internal static extern bool TranslateMessage([In] ref NativeMessage lpMsg);
[DllImport("user32.dll")]
internal static extern IntPtr DispatchMessage([In] ref NativeMessage lpMsg);
}