using System;
using XP.Hardware.RaySource.Comet;
using XP.Hardware.RaySource.Comet.Messages.Commands;
using XP.Hardware.RaySource.Comet.Messages.Responses;
namespace XP.Hardware.RaySource.Comet.Host.Pipe
{
///
/// 命令分发器
/// 根据命令类型分发到 CometPviClient 对应方法
///
static class CommandDispatcher
{
///
/// 退出标志,DisconnectCommand 处理后设置为 true
///
public static bool ShouldExit { get; private set; }
///
/// 分发命令到 CometPviClient 对应方法
///
/// 待处理的命令
/// 处理结果响应
public static RaySourceResponse Dispatch(RaySourceCommand command)
{
try
{
switch (command.CommandType)
{
case "Initialize":
return HandleInitialize((InitializeCommand)command);
case "ConnectVariables":
return HandleConnectVariables();
case "TurnOn":
return HandleTurnOn();
case "TurnOff":
return HandleTurnOff();
case "SetVoltage":
return HandleSetVoltage((SetVoltageCommand)command);
case "SetCurrent":
return HandleSetCurrent((SetCurrentCommand)command);
case "ReadVoltage":
return HandleReadVoltage();
case "ReadCurrent":
return HandleReadCurrent();
case "ReadSystemStatus":
return HandleReadSystemStatus();
case "ReadErrors":
return HandleReadErrors();
case "Disconnect":
return HandleDisconnect();
case "TxiOn":
return HandleTxiOn();
case "TxiOff":
return HandleTxiOff();
case "WarmUp":
return HandleWarmUp();
case "Training":
return HandleTraining();
case "FilamentCalibration":
return HandleFilamentCalibration();
case "AutoCenter":
return HandleAutoCenter();
case "SetPowerMode":
return HandleSetPowerMode((SetPowerModeCommand)command);
default:
return new OperationResponse
{
Success = false,
ErrorMessage = $"未知的命令类型:{command.CommandType}"
};
}
}
catch (Exception ex)
{
return new OperationResponse
{
Success = false,
ErrorMessage = $"命令处理异常:{ex.Message}"
};
}
}
///
/// 等待 PVI 回调链完成的超时时间(毫秒)
/// PVI Service.Connect() → Service_Connected → CPU.Connect() → Cpu_Connected 整个链路需要时间
///
private const int PviConnectTimeoutMs = 30000;
private static RaySourceResponse HandleInitialize(InitializeCommand cmd)
{
// PVI 回调链依赖 WinForms 消息泵派发事件
// 不能用 ManualResetEventSlim.Wait() 阻塞 UI 线程,否则回调无法触发
// 改用带消息泵的轮询等待,保持 Application.DoEvents() 运转
bool completed = false;
bool errorOccurred = false;
string errorMessage = null;
// 订阅连接状态变更事件
EventHandler stateHandler = (sender, state) =>
{
if (state == PviConnectionState.ServiceConnected)
{
Console.Error.WriteLine("[Host] PVI 回调链完成,ServiceConnected");
completed = true;
}
};
// 订阅错误事件(PVI 连接可能失败)
EventHandler errorHandler = (sender, msg) =>
{
errorOccurred = true;
errorMessage = msg;
Console.Error.WriteLine($"[Host] PVI 连接错误:{msg}");
completed = true;
};
CometPviClient.ConnectionStateChanged += stateHandler;
CometPviClient.ErrorOccurred += errorHandler;
try
{
CometPviClient.Initialize(cmd.IpAddress, cmd.Port, cmd.CpuName, cmd.SourcePort, cmd.StationNumber);
// 带消息泵的等待循环,保持 UI 消息派发,让 PVI 回调能触发
var deadline = DateTime.UtcNow.AddMilliseconds(PviConnectTimeoutMs);
while (!completed && DateTime.UtcNow < deadline)
{
System.Windows.Forms.Application.DoEvents();
System.Threading.Thread.Sleep(50);
}
if (!completed)
{
return new OperationResponse
{
Success = false,
ErrorMessage = "PVI 连接超时,回调链未在规定时间内完成"
};
}
if (errorOccurred)
{
return new OperationResponse
{
Success = false,
ErrorMessage = $"PVI 连接失败:{errorMessage}"
};
}
return new OperationResponse { Success = true };
}
finally
{
CometPviClient.ConnectionStateChanged -= stateHandler;
CometPviClient.ErrorOccurred -= errorHandler;
}
}
private static RaySourceResponse HandleConnectVariables()
{
CometPviClient.ConnectVariables();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleTurnOn()
{
CometPviClient.TurnOn();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleTurnOff()
{
CometPviClient.TurnOff();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleSetVoltage(SetVoltageCommand cmd)
{
CometPviClient.SetVoltage(cmd.Voltage);
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleSetCurrent(SetCurrentCommand cmd)
{
CometPviClient.SetCurrent(cmd.Current);
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleReadVoltage()
{
var voltage = CometPviClient.ReadVoltage();
return new OperationResponse { Success = true, Data = voltage };
}
private static RaySourceResponse HandleReadCurrent()
{
var current = CometPviClient.ReadCurrent();
return new OperationResponse { Success = true, Data = current };
}
private static RaySourceResponse HandleReadSystemStatus()
{
var status = CometPviClient.ReadSystemStatus();
return new StatusResponse
{
Success = true,
SetVoltage = status.SetVoltage,
ActualVoltage = status.ActualVoltage,
SetCurrent = status.SetCurrent,
ActualCurrent = status.ActualCurrent,
IsXRayOn = status.IsXRayOn,
WarmUpStatus = status.WarmUpStatus,
VacuumStatus = status.VacuumStatus,
StartUpStatus = status.StartUpStatus,
AutoCenterStatus = status.AutoCenterStatus,
FilamentAdjustStatus = status.FilamentAdjustStatus,
IsInterlockActive = status.IsInterlockActive,
WatchdogStatus = status.WatchdogStatus,
PowerMode = status.PowerMode,
TxiStatus = status.TxiStatus
};
}
private static RaySourceResponse HandleReadErrors()
{
var errors = CometPviClient.ReadErrors();
return new ErrorDataResponse
{
Success = true,
SystemError = errors.SystemError,
HSGError = errors.HSGError,
TubeError = errors.TubeError,
TubeVacError = errors.TubeVacError
};
}
private static RaySourceResponse HandleDisconnect()
{
CometPviClient.Disconnect();
ShouldExit = true;
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleTxiOn()
{
CometPviClient.TxiOn();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleTxiOff()
{
CometPviClient.TxiOff();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleWarmUp()
{
CometPviClient.WarmUp();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleTraining()
{
CometPviClient.Training();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleFilamentCalibration()
{
CometPviClient.FilamentCalibration();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleAutoCenter()
{
CometPviClient.AutoCenter();
return new OperationResponse { Success = true };
}
private static RaySourceResponse HandleSetPowerMode(SetPowerModeCommand cmd)
{
CometPviClient.SetPowerMode(cmd.Mode);
return new OperationResponse { Success = true };
}
}
}